вторник, 28 июня 2011 г.

Syser: Windows kernel graphics

Syser Sysboot.sys 
Решил посмотреть как устроен графический вывод в ядернов дебаггере Syser.

Забегая вперед:
    Перехват Eng* GDI с создание FrameBuffer;
    Перехват Dxkg с создание FrameBuffer;
 Выполняется по средству перехвата ZwLoadDriver с возможностью перехватить инитиализацию двайвера(адаптера)

 Ссылки  kernel graphics : 
http://msdn.microsoft.com/en-us/library/ff566549%28v=VS.85%29.aspx
http://msdn.microsoft.com/en-us/library/hh285672%28v=VS.85%29.aspx
http://www.google.com/codesearch#2WD-6k1zLRA/src/VBox/Additions/WINNT/Graphics/&q=DxgkDdiSetVidPnSourceAddress&type=cs

Декомпилированый Driver Entry 
NTSTATUS __stdcall DriverEntry(
            PDRIVER_OBJECT DriverObject, 
            PUNICODE_STRING RegistryPath)
{
  NTSTATUS result; // eax@2
  void *v3; // eax@4
  LSA_UNICODE_STRING SymbolicLinkName; // [sp+Ch] [bp-2Ch]@4
  PDEVICE_OBJECT DeviceObject; // [sp+14h] [bp-24h]@3
  LSA_UNICODE_STRING DestinationString; // [sp+18h] [bp-20h]@3
  CPPEH_RECORD ms_exc; // [sp+20h] [bp-18h]@7
//BootVid (VidDisplayStringXY, VidSolidColorFill)
// do { KeDelayExecutionThread
//  in      al, 64h, in      al, 60h , check eax } while(index < 250)
  if ( OutVidStr_PressKey_to_exit(
         (ULONG)"             Press \"ESC\" to cancel loading Syser Boot Module           ",
         -10000) == 1 )
  {
    result = 0xC0000001u;
  }
  else
  {
    RtlInitUnicodeString(&DestinationString, L"\\Device\\SyserBoot");
    result = IoCreateDevice(DriverObject, 0x24u, &DestinationString, 0x23u, 0, 1u, &DeviceObject);
    if ( result >= 0 )
    {
      LOBYTE(DeviceObject->Flags) &= 0x7Fu;
      RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\SyserBoot");
      IoCreateSymbolicLink(&SymbolicLinkName, &DestinationString);
      memset(&g_LPMasterIrp, 0, 0x1Cu);
      ptrDeviceExtension = (int)DeviceObject->DeviceExtension;
      memset((void *)ptrDeviceExtension, 0, 0x24u);
      *(_DWORD *)ptrDeviceExtension = 36;
      *(_DWORD *)(ptrDeviceExtension + 4) = 104192;
      *(_DWORD *)(ptrDeviceExtension + 24) = sub_13A9E;
      v3 = (void *)sub_13B3C(0x20u);
      if ( v3 )
        P = sub_10676(v3);
      else
        P = 0;
      ReadRegistryCfg();
      ms_exc.disabled = 0;
      if ( FlagVideoHookDisabled )
      {
        DbgPrint("SyserBoot : Video Hook is disabled!\n");
      }
      else
      {
        SetHookZwSetSystemInfomation();
        SetHookZwLoadDriver();
      }
      ms_exc.disabled = -1;
      memset(DriverObject->MajorFunction, (int)DefaultDispatcher, 0x6Cu);
      DriverObject->MajorFunction[0] = (PDRIVER_DISPATCH)DefaultDispatcher2;
      DriverObject->MajorFunction[2] = (PDRIVER_DISPATCH)DefaultDispatcher2;
      DriverObject->MajorFunction[14] = (PDRIVER_DISPATCH)sub_10586;
      DriverObject->DriverUnload = (PDRIVER_UNLOAD)UnloadDriver;
      PsSetLoadImageNotifyRoutine(LoadImageNotifyRoutine);
      result = 0;
    }
  }
  return result;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
char __cdecl SetHookZwLoadDriver()
{
  PVOID addressZwLoadDriver; // eax@1
  char result; // al@5
  LSA_UNICODE_STRING DestinationString; // [sp+0h] [bp-8h]@1

  RtlInitUnicodeString(&DestinationString, L"ZwLoadDriver");
  addressZwLoadDriver = MmGetSystemRoutineAddress(&DestinationString);
  if ( addressZwLoadDriver && *(_BYTE *)addressZwLoadDriver == -72 )
  {
    callNumber_ZwLoadDriver = *(_DWORD *)((char *)addressZwLoadDriver + 1);
    Original_ZwLoadDriver = (int (__stdcall *)(_DWORD))*(&KeServiceDescriptorTable + callNumber_ZwLoadDriver);
    cr0_mem_protect((int)Original_ZwLoadDriver);
    *(&KeServiceDescriptorTable + callNumber_ZwLoadDriver) = Hooked_ZwLoadDriver;
    Restore_cr0_reg_();
    if ( HookIsSuccess )
      DbgPrint("SyserBoot : ZwLoadDriver Hook Success !\n");
    result = 1;
  }
  else
  {
    DbgPrint("SyserBoot : Fail to hook ZwLoadDriver\n");
    result = 0;
  }
  return result;
}
//////////////////////////////////////////////////////////////////////////
.text:000115CA                      cr0_mem_protect proc near               ; CODE XREF: SetHookZwLoadDriver+3F p
.text:000115CA                                                              ; SetHookZwSetSystemInfomation+3F p
.text:000115CA
.text:000115CA                      var_4           = dword ptr -4
.text:000115CA
.text:000115CA 51                                   push    ecx
.text:000115CB                      ; 5:   if ( byte_1577F & 0x80 )
.text:000115CB F6 05 7F 57 01 00 80                 test    byte_1577F, 80h
.text:000115D2 C7 44 24 00 FF FF FE+                mov     [esp+4+var_4], 0FFFEFFFFh
.text:000115DA 74 0E                                jz      short loc_115EA
.text:000115DC                      ; 7:     v2 = a1;
.text:000115DC 50                                   push    eax
.text:000115DD                      ; 8:     __asm { mov     eax, cr0 }
.text:000115DD 0F 20 C0                             mov     eax, cr0
.text:000115E0                      ; 9:     _EAX &= 0xFFFEFFFFu;
.text:000115E0 23 44 24 04                          and     eax, [esp+8+var_4]
.text:000115E4                      ; 10:     __asm { mov     cr0, eax }
.text:000115E4 0F 22 C0                             mov     cr0, eax
.text:000115E7                      ; 11:     result = v2;
.text:000115E7 58                                   pop     eax
.text:000115E8 59                                   pop     ecx
.text:000115E9 C3                                   retn
.text:000115EA                      ; ---------------------------------------------------------------------------
.text:000115EA                      ; 15:     __asm { mov     eax, cr0 }
.text:000115EA
.text:000115EA                      loc_115EA:                              ; CODE XREF: cr0_mem_protect+10 j
.text:000115EA 0F 20 C0                             mov     eax, cr0
.text:000115ED                      ; 16:     cr0_old_val = _EAX;
.text:000115ED A3 7C 57 01 00                       mov     dword ptr cr0_old_val, eax
.text:000115F2                      ; 17:     result = _EAX & 0xFFFEFFFF;
.text:000115F2 23 44 24 00                          and     eax, [esp+4+var_4]
.text:000115F6                      ; 18:     __asm { mov     cr0, eax }
.text:000115F6 0F 22 C0                             mov     cr0, eax
.text:000115F9 59                                   pop     ecx
.text:000115FA C3                                   retn
.text:000115FA                      cr0_mem_protect endp

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////// Перехватанный  ZwLoadDriver в этом перехвате осуществдяется перехват
////////// DXGKrnl IRP_MJ_INTERNAL_DEVICE_CONTROL
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
;
;
;
.text:00011AE3                 push    esi             ; _DWORD
.text:00011AE4                 call    Original_ZwLoadDriver
;
;
;
.text:00011B8B loc_11B8B:                              ; CODE XREF: Hooked_ZwLoadDriver+8A j
.text:00011B8B                 mov     edx, [ebp+DeviceObject]
.text:00011B8E                 mov     eax, [edx+8]
.text:00011B91                 mov     ecx, [eax+74h]
.text:00011B94 ; 29:           if ( (int (__stdcall *)(int, int))DeviceObject->DriverObject->MajorFunction[15] != DXGKrnl_HookedInternalDeviceControl )
.text:00011B94                 mov     eax, offset DXGKrnl_HookedInternalDeviceControl
.text:00011B99                 cmp     ecx, eax
.text:00011B9B                 jz      short loc_11BA9
.text:00011B9D ; 31:             DXGKrnl_DispatchInternalDeviceControl = (int (__stdcall *)(_DWORD, _DWORD))DeviceObject->DriverObject->MajorFunction[15];
.text:00011B9D                 mov     DXGKrnl_DispatchInternalDeviceControl, ecx
.text:00011BA3 ; 32:             DeviceObject->DriverObject->MajorFunction[15] = (PDRIVER_DISPATCH)DXGKrnl_HookedInternalDeviceControl;
.text:00011BA3                 mov     ecx, [edx+8]
.text:00011BA6                 mov     [ecx+74h], eax

///////////////Перехват DXGKrnl->DxgkInitialize
DXGKrnl_HookedInternalDeviceControl;
.text:000116AD ; 10:   lpDXGKrnl_DxgkInitialize = *(_DWORD *)(a2 + 60);
.text:000116AD                 push    esi
.text:000116AE                 mov     esi, [ecx+3Ch]
.text:000116B1 ; 11:   v5 = *(_DWORD *)(v4 + 12);
.text:000116B1                 push    edi
.text:000116B2                 mov     edi, [eax+0Ch]
.text:000116B5 ; 12:   Result = DXGKrnl_DispatchInternalDeviceControl(a1, a2);
.text:000116B5                 push    ecx             ; _DWORD
.text:000116B6                 push    [ebp+arg_0]     ; _DWORD
.text:000116B9                 call    DXGKrnl_DispatchInternalDeviceControl
.text:000116BF ; 13:   if ( v5 == 0x23003F )
.text:000116BF                 cmp     edi, 23003Fh
.text:000116C5                 mov     [ebp+Result], eax
.text:000116C8                 jnz     short loc_116FB
.text:000116CA ; 15:     if ( v2 == 4 )
.text:000116CA                 cmp     ebx, 4
.text:000116CD                 jnz     short loc_116FB
.text:000116CF ; 17:       if ( lpDXGKrnl_DxgkInitialize )
.text:000116CF                 test    esi, esi
.text:000116D1                 jz      short loc_116FB
.text:000116D3 ; 19:         DXGKrnl_DxgkInitialize = *(int (__stdcall **)(_DWORD, _DWORD, _DWORD))lpDXGKrnl_DxgkInitialize;
.text:000116D3                 mov     eax, [esi]
.text:000116D5                 mov     DXGKrnl_DxgkInitialize, eax
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int __stdcall Hook_DXGKrnl_DxgkInitialize(int a1, int a2, const void *a3)
{
  DRIVER_INITIALIZATION_DATA DxDriverInitializeData; // [sp+8h] [bp-F8h]@1
  int (__stdcall *v5)(int, int); // [sp+54h] [bp-ACh]@1
  int (__stdcall *v6)(int, int); // [sp+58h] [bp-A8h]@1
  NTSTATUS (__stdcall *v7)(HANDLE, int); // [sp+A8h] [bp-58h]@1
  int (__stdcall *v8)(int, int); // [sp+ACh] [bp-54h]@1

  memcpy(&DxDriverInitializeData, a3, 0xF8u);
  memset(&g_FrameBufferPhysAddress, 0, 0x18u);
  sub_1070E(P);
  ReadRegistryCfg();
  g_OrigDxgkDdiSetVidPnSourceAddress = (int (__stdcall *)(_DWORD, _DWORD))v7;
  g_OrigDxgkDdiCreateAllocation = v5;
  g_OrigDxgkDdiDestroyAllocation = v6;
  g_OrigDxgkDdiSetVidPnSourceVisibility = v8;
  v7 = HookedDxgkDdiSetVidPnSourceAddress;
  v5 = HookedDxgkDdiCreateAllocation;
  v6 = HookedDxgkDdiDestroyAllocation;
  v8 = HookedDxgkDdiSetVidPnSourceVisibility;
  return DXGKrnl_DxgkInitialize(a1, a2, &DxDriverInitializeData);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////Создание Graphic Frame Buffer
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
NTSTATUS __stdcall HookedDxgkDdiSetVidPnSourceAddress(HANDLE hAdapter, int pSetVidPnSourceAddress)
{
  int pSetVidPnSourceAddress2; // edi@1
  int pSetVidPnSourceAddress3; // esi@2
  int lpFrameBufferPhysAddress; // eax@5
  NTSTATUS Status; // [sp+Ch] [bp+8h]@1

  pSetVidPnSourceAddress2 = pSetVidPnSourceAddress;
  Status = g_OrigDxgkDdiSetVidPnSourceAddress(hAdapter, pSetVidPnSourceAddress);
  if ( *(_BYTE *)(pSetVidPnSourceAddress2 + 284) & 1 )
  {
    sub_1103E((int)P, (int)&pSetVidPnSourceAddress, pSetVidPnSourceAddress2 + 16);
    pSetVidPnSourceAddress3 = pSetVidPnSourceAddress;
    if ( pSetVidPnSourceAddress )
    {
      if ( *(_BYTE *)(pSetVidPnSourceAddress + 16) )
      {
        SyserBootReleaseFrameBufferMap((int)&g_FrameBufferPhysAddress);
        if ( SyserBootAllocateFrameBufferMap(
               *(_DWORD *)(pSetVidPnSourceAddress2 + 8),
               *(_DWORD *)(pSetVidPnSourceAddress2 + 12),
               *(_DWORD *)(pSetVidPnSourceAddress3 + 44) * *(_DWORD *)(pSetVidPnSourceAddress3 + 28),
               (int)&g_FrameBufferPhysAddress) )
        {
          *(_DWORD *)(pSetVidPnSourceAddress3 + 36) = g_FrameBufferPhysAddress;
          lpFrameBufferPhysAddress = g_FrameBufferPhysAddress;
          *(_DWORD *)(pSetVidPnSourceAddress3 + 40) = g_FrameBufferPhysAddress;
          ValidateFrameBufferPhysAddress(
            *(_DWORD *)(pSetVidPnSourceAddress3 + 24),
            *(_DWORD *)(pSetVidPnSourceAddress3 + 28),
            *(_DWORD *)(pSetVidPnSourceAddress3 + 32),
            lpFrameBufferPhysAddress,
            *(_DWORD *)(pSetVidPnSourceAddress3 + 44));
          *(_DWORD *)(ptrDeviceExtension + 8) = &g_LPMasterIrp;
          if ( HookIsSuccess )
          {
            DbgPrint(
              "SyserBoot : DxgkDdiSetVidPnSourceAddress hAllocation = %08X\n",
              *(_DWORD *)(pSetVidPnSourceAddress2 + 16));
            DbgPrint(
              "            Mode Change %d X %d X %d Pitch %d PhysAddr[%08X] FrameBuffer[%08X]\n",
              *(_DWORD *)(pSetVidPnSourceAddress3 + 24),
              *(_DWORD *)(pSetVidPnSourceAddress3 + 28),
              *(_DWORD *)(pSetVidPnSourceAddress3 + 32),
              *(_DWORD *)(pSetVidPnSourceAddress3 + 44),
              *(_DWORD *)(pSetVidPnSourceAddress2 + 8),
              *(_DWORD *)(pSetVidPnSourceAddress3 + 40));
          }
        }
        else
        {
          if ( HookIsSuccess )
            DbgPrint(
              "SyserBoot : DxgkDdiSetVidPnSourceAddress fail to map PhysAddr 0x%08X\n",
              *(_DWORD *)(pSetVidPnSourceAddress2 + 8));
        }
      }
    }
  }
  return Status;
}
char __stdcall SyserBootAllocateFrameBufferMap(int PrimarySegment, int PrimaryAddress, int NumberOfBytes, int lpFrameBufferMap)
{
  KIRQL v4; // al@1
  char result; // al@4
  int lpFBMap; // eax@5

  v4 = KeGetCurrentIrql();
  if ( v4 )
  {
    if ( HookIsSuccess )
      DbgPrint("SyserBoot : AllocateFrameBufferMap IRQL = %08X\n", v4);
    *(_DWORD *)lpFrameBufferMap = 0;
    result = 0;
  }
  else
  {
    lpFBMap = MmMapIoSpace(PrimarySegment, PrimaryAddress, NumberOfBytes, 2);
    *(_DWORD *)lpFrameBufferMap = lpFBMap;
    if ( lpFBMap )
    {
      *(_DWORD *)(lpFrameBufferMap + 8) = PrimarySegment;
      *(_DWORD *)(lpFrameBufferMap + 12) = PrimaryAddress;
      *(_DWORD *)(lpFrameBufferMap + 16) = NumberOfBytes;
      result = 1;
    }
    else
    {
      result = 0;
    }
  }
  return result;
}
/////////////////////////////////////////////////////////////////////////////////////
Так же перехваты GDI
DrvDisablePDEV
DrvEnableSurface             //пустой
DrvGetDirectDrawInfo
DrvEnableDirectDraw
DrvEnablePDEV

Комментариев нет:

Отправить комментарий