在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
;====================================================================