xp下用驱动直接写显卡显存

在vmware6中调试通过。屏幕被画成白色

pci操作部分查一下pci端口操作方面的资料。

  .586P    ; 保护模式,里面可能会有特权模式指令
  .model flat,stdcall
  option casemap:none
  
;====================================================================
; Include 文件定义
;====================================================================
include  ntddk.inc
include  ntstatus.inc
include  hal.inc
includelib hal.lib
include  ntoskrnl.inc
includelib ntoskrnl.lib
Include w2kundoc.inc
Include strings.mac

;=================================================================
CTL_USER  equ CTL_CODE(0F000h,0f00h,METHOD_BUFFERED,FILE_ANY_ACCESS)
CTL_Start  equ CTL_USER + 4*1
CTL_Stop  equ CTL_USER + 4*2
CTL_Read  equ CTL_USER + 4*3
CTL_Write  equ CTL_USER + 4*4

VideoCardClassID equ 00030000h
VideoCardBassAddressIndex equ 5
GetVideoInfo PROTO  ;
GetPCIDeviceBassAddress PROTO :DWORD ;获得显卡基地址
;====================================================================
; 数据段
;====================================================================
  .data
; 字符串定义
DD_DEVICE_NAME db '/Device/gookoonvga',0
DD_SYMBOL_NAME db '/DosDevices/gookoonvga',0

;====================================================================
; 代码段
;====================================================================
  .code
;====================================================================
; Win32 控制处理函数
;====================================================================
_Dispatch  proc uses edi esi ebx DriverObject:DWORD,_Irp:DWORD

  mov  edi,_Irp
  mov (_IRP ptr [edi]).IoStatus.Information,0
  mov (_IRP ptr [edi]).IoStatus.Status,STATUS_SUCCESS
  mov esi,(_IRP PTR [edi]).Tail.Overlay.CurrentStackLocation
  movzx eax,(IO_STACK_LOCATION ptr [esi]).MajorFunction
  .if  eax == IRP_MJ_CREATE   ; 处理IRP_MJ_CREATE
  .elseif eax == IRP_MJ_CLOSE    ; 处理IRP_MJ_CLOSE
  .elseif eax == IRP_MJ_DEVICE_CONTROL ; 处理我们的控制消息
  ; mov eax,(_IRP ptr [edi]).UserBuffer         ; 输出缓冲区
  ; mov eax,(IO_STACK_LOCATION ptr [esi]).Parameters.DeviceIoControl.OutputBufferLength
  ; mov eax,(_IRP ptr [edi]).AssociatedIrp.SystemBuffer     ; 输入缓冲区
  ; mov eax,(IO_STACK_LOCATION ptr [esi]).Parameters.DeviceIoControl.InputBufferLength
  ; 上面是我们常用的参数。直接在上面修改
   mov eax,(IO_STACK_LOCATION ptr [esi]).Parameters.DeviceIoControl.IoControlCode
   .if  eax == CTL_Start   ; 启动

   .elseif eax == CTL_Stop    ; 停止

   .elseif eax == CTL_Read    ; 读取

   .elseif eax == CTL_Write   ; 写入

   .endif
  .endif
  invoke IoCompleteRequest,_Irp,IO_NO_INCREMENT
  mov eax,STATUS_SUCCESS
  ret
_Dispatch  endp
;====================================================================
; 驱动卸载时候的操作:删除链接,删除设备
;====================================================================
_Unload  proc uses edi esi ebx DriverObject:DWORD
  local SymbolName:UNICODE_STRING
  local pDeviceObject:PDEVICE_OBJECT
  local TempName:UNICODE_STRING

  pushad
  .if DriverObject
   invoke RtlInitAnsiString,addr TempName,offset DD_SYMBOL_NAME
   invoke RtlAnsiStringToUnicodeString,addr SymbolName,addr TempName,TRUE
   invoke IoDeleteSymbolicLink,addr SymbolName
   invoke RtlFreeUnicodeString,addr SymbolName

   mov edi,DriverObject
   mov esi,(DRIVER_OBJECT ptr [edi]).DeviceObject
   .while esi
    mov edi,(DEVICE_OBJECT ptr [esi]).NextDevice
    invoke IoDeleteDevice,esi
    mov esi,edi
   .endw
  .endif
  popad
  ret
_Unload  endp

;====================================================================
; 驱动程序入口
;====================================================================
DriverEntry  proc uses edi esi ebx DriverObj:DWORD,RegistryPath:DWORD
  local DeviceName:UNICODE_STRING
  local SymbolName:UNICODE_STRING
  local pDeviceObject:PDEVICE_OBJECT
  local TempName:UNICODE_STRING

  
  
  pushad
  mov  eax,DriverObj
  assume eax:ptr DRIVER_OBJECT
  mov  [eax].DriverUnload,offset _Unload
  lea  edi,[eax].MajorFunction
  lea  eax,_Dispatch
  mov  [edi+ IRP_MJ_CREATE *4],eax    ; 打开
  mov  [edi+ IRP_MJ_CLOSE  *4],eax    ; 关闭
  mov  [edi+ IRP_MJ_DEVICE_CONTROL  *4],eax ; 控制
;  mov  ecx,IRP_MJ_MAXIMUM_FUNCTION
;  rep  stosd
  assume eax:nothing
 ;====================================================================
 ; 创建设备
  invoke RtlInitAnsiString,addr TempName,offset DD_DEVICE_NAME
  invoke RtlAnsiStringToUnicodeString,addr DeviceName,addr TempName,TRUE
  invoke RtlInitAnsiString,addr TempName,offset DD_SYMBOL_NAME
  invoke RtlAnsiStringToUnicodeString,addr SymbolName,addr TempName,TRUE
 ;====================================================================
  invoke IoCreateDevice,DriverObj,0,addr DeviceName,FILE_DEVICE_NULL,0,NULL,addr pDeviceObject
  .if  eax != STATUS_SUCCESS
   jmp Err
  .endif
  invoke IoCreateSymbolicLink,addr SymbolName,addr DeviceName
  .if  eax != STATUS_SUCCESS
   mov edi,DriverObj  ; 出错,删除所有设备退出
   mov esi,(DRIVER_OBJECT ptr [edi]).DeviceObject
   .while esi
    mov edi,(DEVICE_OBJECT ptr [esi]).NextDevice
    invoke IoDeleteDevice,esi
    mov esi,edi
   .endw
   jmp Err
  .endif
  CALL GetVideoInfo
;====================================================================
Err: ; 出错直接返回
  invoke RtlFreeUnicodeString,addr DeviceName
  invoke RtlFreeUnicodeString,addr SymbolName
  popad
  xor eax,eax
  ret
DriverEntry  endp
;======================================================================
strcmpi Proc uses esi edi _Str1,_Str2
 mov esi,_Str1
 mov edi,_Str2
 xor ecx,ecx
 .While TRUE
  .if !byte ptr [esi+ecx] || !byte ptr [edi+ecx]
   .Break
  .endif
  mov al,byte ptr [esi+ecx]
  .if al >= "A" && al <="Z"
   or al,20h
  .endif
  .if al != byte ptr [edi+ecx]
   mov eax,1
   ret
  .endif
  inc ecx
 .EndW
 mov eax,0
 ret
strcmpi EndP
DWORD_In PROC io_Port:DWORD       
  mov   Edx,io_Port    
  in   eax,dx     
  RET
DWORD_In ENDP
DWORD_Out PROC io_Port:DWORD,val:DWORD
                  mov   Edx,io_Port    
                  mov   eax,val    
                  out   dx,eax    
                  ret
DWORD_Out ENDP

GetPCIDeviceBassAddress Proc DeviceClassID:DWORD
        LOCAL io_CF8:DWORD;       ;   port   0xcf8    
        LOCAL io_CFC:DWORD   ;       ;   port   0xcfc    
        LOCAL io_read:DWORD
        LOCAL i:DWORD   
        ;int 3
          MOV io_CF8,80000000h;       ;because   the   first   bit   is   enable/disable
         .While io_CF8<80FFFF00h                            ;so   must   be   1,so   from   0x800000000    
                   
                 
                  INVOKE DWORD_Out,0cf8h,io_CF8    
                  INVOKE DWORD_In,0cfch;
                  MOV io_CFC,EAX    
                  MOV i,0

;pci都有一个内存结构。这个结构存放了pci卡相关的信息.
                  .if   io_CFC!=0ffffffffh     ;if   =0xffffffff,then   is   a   invalid     
                     ;bus   number   and   device   number     
                          .WHILE   i<=15   
                          MOV EAX,io_CF8
                          MOV ECX,i
                          LEA EAX,[EAX+4*ECX]
                          PUSH EAX
                          PUSH 0cf8h
                          CALL DWORD_Out ;read   DWORD
                          INVOKE DWORD_In,0cfch;
                      MOV io_read,EAX   
                         

                         .if i==2    
                          shr eax,8
                          .if eax==DeviceClassID
                           MOV EAX,io_CF8
                          MOV ECX,i
                           LEA EAX,[EAX+4*VideoCardBassAddressIndex]
                           PUSH EAX
                           PUSH 0cf8h
                           CALL DWORD_Out ;read   DWORD
                           INVOKE DWORD_In,0cfch;
                           ret
                          .endif
      .endif
                          INC i  
                         .ENDW
                  .endif   
                  ;io_CF8+=0x800;            
                  MOV EAX,io_CF8
                  LEA EAX,[EAX+800h]
                  MOV io_CF8,EAX
 .EndW        
  
  ret

GetPCIDeviceBassAddress ENDP
EnumPCIDevice Proc
  Local BusID,DeviceID,FuncID
  Local DevID,VenID,ClassID
  Local ConfigReg
  Local szBuffer[1024]:BYTE
  
  xor eax,eax
  mov BusID,eax
  mov DeviceID,eax
  mov FuncID,eax
  
;  invoke _lstrcpy,addr szBuffer,CTEXT("Bus# Device# Func# Vendor# Device# Class#",13,10)
  
  .While BusID < 256
   mov DeviceID,0
   .While DeviceID < 32
    mov FuncID,0
    .While FuncID < 8
     mov eax,80000000h
     mov ecx,FuncID
     shl ecx,8
     or eax,ecx
     mov ecx,DeviceID
     shl ecx,11
     or eax,ecx
     mov ecx,BusID
     shl ecx,16
     or eax,ecx
     mov ConfigReg,eax
     
     mov dx,0CF8h
     out dx,eax
     mov dx,0CFCh
     in eax,dx
     .if ax != 0FFFFh
      mov ecx,eax
      and ecx,0FFFFh
      mov VenID,ecx
      mov ecx,eax
      shr ecx,16
      mov DevID,ecx
      
      mov eax,ConfigReg ;Read ClassID
      or eax,08h
      mov dx,0CF8h
      out dx,eax
      mov dx,0CFCh
      in eax,dx
      shr eax,8
      
      mov ClassID,eax
      
      
      .if eax==30000h
      
      mov eax,ConfigReg ;read video card base address line address
      LEA eax,[eax+5*4]
      mov dx,0CF8h
      out dx,eax
      mov dx,0CFCh
      in eax,dx

      ret
     
      .endif    
          
      .if !FuncID
       mov eax,ConfigReg ;Read HeaderType
       or eax,0Ch
       mov dx,0CF8h
       out dx,eax
       mov dx,0CFCh
       in eax,dx
       shr eax,16
       and eax,0FFh
       and eax,010000000b
       cmp eax,0
       jnz @nextfunc
       jz @nextdevice
      .endif
     .endif
@nextfunc:    inc FuncID
    .EndW
@nextdevice:   inc DeviceID
   .EndW
   inc BusID
  .EndW
  ret
EnumPCIDevice EndP


GetVideoInfo PROC
  Local pSystemProcess,pTargetProcess,pTargetThread
  Local pListHead,pNextEntry,pThNextEntry
  Local dwVersion,Offset_ListEntry,Offset_ImageName,Offset_ThreadListHead,Offset_ThreadListEntry,Offset_Alartable
  Local pApc,pMappedAddress,dwSize
  Local ApcState:KAPC_STATE
  LOCAL contexti386:CONTEXT
  LOCAL contextVideo:CONTEXT
  LOCAL videoStruct:DWORD
  LOCAL addrtr:DWORD
  LOCAL addrtrsize:DWORD
  LOCAL scWidth:DWORD
  LOCAL scHeight:DWORD
  LOCAL  mapAddr:DWORD
  assume eax:nothing
  
  ;LOCAL OldIrql:DWORD

  invoke PsGetVersion,0,addr dwVersion,0,0
  .if dwVersion == 0
   mov Offset_ListEntry,0A0h
   mov Offset_ImageName,1FCh
   mov Offset_ThreadListHead,270h
   mov Offset_ThreadListEntry,240h
   mov Offset_Alartable,158h
   
  .elseif dwVersion == 1
   mov Offset_ListEntry,088h
   mov Offset_ImageName,174h
   mov Offset_ThreadListHead,190h
   mov Offset_ThreadListEntry,22Ch
   mov Offset_Alartable,164h
   
  .endif
  
  invoke PsGetCurrentProcess
  mov pSystemProcess,eax
  
  mov esi,pSystemProcess
  assume ebx: ptr LIST_ENTRY
  assume edi: ptr LIST_ENTRY
  
  .if !pSystemProcess
   jmp exit
  .endif
  
  invoke DbgPrint,$CTA0("%p %p"),Offset_ListEntry,Offset_ImageName
  
  
  mov ebx,esi
  add ebx,Offset_ListEntry ;ebx = ListHead
  mov eax,[ebx].Flink
  mov pNextEntry,eax
  
  mov pTargetProcess,0
  .While ebx != pNextEntry
   mov esi,pNextEntry
   sub esi,Offset_ListEntry
   add esi,Offset_ImageName
   invoke _stricmp,esi,$CTA0("csrss.exe")
   .if !eax
    invoke DbgPrint,esi
    sub esi,Offset_ImageName
    mov pTargetProcess,esi
    .Break
   .endif
   mov edi,pNextEntry
   mov edi,[edi].Flink
   mov pNextEntry,edi
  .EndW
  
  .if !pTargetProcess
   invoke DbgPrint,$CTA0("NOT FOUND explorer.exe")
   jmp exit
  .endif
  
  ;INVOKE KeRaiseIrql,HIGH_LEVEL,addr OldIrql ;;HIGH_LEVEL
  INVOKE GetPCIDeviceBassAddress,VideoCardClassID 
  MOV addrtr,EAX
  MOV addrtrsize,07FFFFFFh
 ; INVOKE MmMapIoSpace,addrtr,addrtrsize,MmNonCached,2
  INVOKE MmMapIoSpace,addrtr,0,addrtrsize,1
  MOV mapAddr,EAX
  MOV scWidth,0
  
  .WHILE scWidth<600
   MOV scHeight,0 
   .WHILE scHeight<800
    MOV DWORD ptr [EAX],0FFFFFFFFh
    ADD EAX,4
    inc scHeight
   .ENDW
    LEA EAX,[EAX+224*4]
   inc scWidth
  .ENDW
  INVOKE KeAttachProcess,pTargetProcess
  INVOKE RtlZeroMemory,addr contexti386,sizeof contexti386
  
  MOV EAX,4F03h
  MOV contexti386.regEax,EAX
  INVOKE Ke386CallBios,10h,addr contexti386
  ;INVOKE KeLowerIrql,addr OldIrql
  
  INVOKE RtlZeroMemory,addr contextVideo,sizeof contextVideo
  INVOKE ExAllocatePool,PagedPool, 1000h
  MOV videoStruct,EAX
  INVOKE RtlZeroMemory,videoStruct,1000h
  
 
  

  MOV EAX,videoStruct
  MOV contextVideo.regEdi,EAX
  MOV EAX,4F01h
  MOV contextVideo.regEax,EAX
  MOV EAX,contexti386.regEbx
  MOV contextVideo.regEcx,EAX
  PUSH CS
  POP EAX
  MOV contextVideo.regSegEs,EAX
  INVOKE Ke386CallBios,10h,addr contextVideo 
  INVOKE ExFreePool,videoStruct
   
  CALL KeDetachProcess
  INVOKE MmUnmapIoSpace,mapAddr,addrtrsize
exit:  
  RET

GetVideoInfo ENDP
;====================================================================
 end DriverEntry
;====================================================================

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

替计划实验室Plan T Labs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值