用驱动直接显存抓屏

 ;goto make           ;直接将显存数据保存为BMP图片,注意:是实验代码!

.386                 ;注意:保存后的BMP图片是垂直倒了90度.不知道怎么弄哈~

.model flat, stdcall;显卡物理地址可以用PCI配置空间获取,这里实验从设备管理器中获取的.

option casemap:none ;作者:成松林   QQ:179641795 Email:cheng_5103@126.com

                     ;转贴请保留作者信息,文章发篇不容易!请大家尊重下吧!!!!!

include d:\masm32\include\w2k\ntstatus.inc

include d:\masm32\include\w2k\hal.inc

include d:\masm32\include\w2k\ntddk.inc

include d:\masm32\include\w2k\win32k.inc

include d:\masm32\include\w2k\ntoskrnl.inc

includelib d:\masm32\lib\w2k\ntoskrnl.lib

includelib d:\masm32\lib\w2k\hal.lib

includelib d:\masm32\lib\w2k\win32k.lib

include d:\masm32\Macros\Strings.mac

.const

       CCOUNTED_UNICODE_STRING   "\\??\\C:\\aa.bmp",uFile_Name,4     ;将显存数据写入文件

.data

       bmphd db 42h,4dh,36h,00h,24h,0,0000,000,0,0,036h,000,000,00,28h,0

             db 000,000,000,04h,000,0,0000,003,0,0,0001,000,18h,00,000,0

             db 000,000,000,00h,24h,0,0c4h,0eh,0,0,0c4h,0eh,000,00,000,0

             db 000,000,000,000,000,0,0000

       DataSize                   dd 1024*768*4               ;注意:显存屏幕数据大小,显示色彩为32位色!

       BmpSize                   dd 0

       File_Handle               dd 0

       ScrnBuffer                 dd 0

       ScrnPhysicalAddress       dd 0f0000000h               ;显存物理地地址,可用PCI配置空间端口CF8、CFC获取.

       ScrnSizeMemory             dd 1280*1024*4             ;显存大小,可在PCI空间获取.这里用支持的最大分辨率.

       DisplayLineAddr           dd 0                       ;调用MmMapIoSpace函数映射的虚拟地址.

       DisplayMDLAddr             dd 0

       OB_AB   OBJECT_ATTRIBUTES <>

       Status   IO_STATUS_BLOCK <>

       ByteOffset LARGE_INTEGER<>

      

.code

;****************************************************************************************************************

DriverEntry proc uses ebx ecx edx esi edi pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING

       invoke MmMapIoSpace,ScrnPhysicalAddress,0,ScrnSizeMemory,FALSE       ;建立显存物理地址到线性地址映射

       mov     DisplayLineAddr,eax                                           ;保存线性地址

       invoke IoAllocateMdl,DisplayLineAddr,ScrnSizeMemory,FALSE,FALSE,NULL;分配显存MDL描述,以便锁定

       .if     eax == 0                                                     ;注意:发现分配太大的内存会失败! 

             invoke MmUnmapIoSpace,DisplayLineAddr,ScrnSizeMemory         ;释放显存映射资源

             ret

       .endif 

       mov     DisplayMDLAddr,eax                                           ;保存分配的显存MDL描述

       invoke MmProbeAndLockPages,DisplayMDLAddr,KernelMode,IoReadAccess OR IoWriteAccess;锁存内存操作

       invoke ExAllocatePool,PagedPool,DataSize                             ;分配内存缓冲,拷贝显存数据

       .if     eax == 0                                                     ;分配失败

               invoke MmUnlockPages,DisplayMDLAddr                         ;解出显存锁定

               invoke IoFreeMdl,DisplayMDLAddr                             ;释放分配的显存MDL描述

               invoke MmUnmapIoSpace,DisplayLineAddr,ScrnSizeMemory         ;释放显存映射资源

               ret

       .endif

       mov     ScrnBuffer,eax                                               ;保存分配的内存缓冲

       mov     edi,ScrnBuffer

       mov     esi,DisplayLineAddr                           ;esi->显存线性地址(手动获取的仅为实验)

       mov     ecx,DisplayLineAddr

       add     ecx,DataSize

       .while   esi < ecx                                   ;拷贝显存数据到本地

               mov   eax,[esi]

               mov   [edi],eax

               add   edi,3                                   ;BMP数据每个象素点=32位色下显存4个字节的最后一个字节去掉.

               add   esi,4

       .endw

       invoke MmUnlockPages,DisplayMDLAddr                   ;解出显存MDL描述锁定

       invoke IoFreeMdl,DisplayMDLAddr                       ;释放分配的显存MDL描述

       invoke MmUnmapIoSpace,DisplayLineAddr,ScrnSizeMemory ;释放显存映射资源

       InitializeObjectAttributes addr OB_AB,addr uFile_Name,OBJ_CASE_INSENSITIVE or OBJ_KERNEL_HANDLE,NULL,NULL;宏native.inc:InitializeObjectAttributes

       invoke ZwCreateFile,addr File_Handle,GENERIC_WRITE,addr OB_AB,addr Status,NULL,FILE_ATTRIBUTE_NORMAL,0,FILE_OVERWRITE_IF,FILE_SYNCHRONOUS_IO_NONALERT,NULL,0

       .if     eax !=0                                       ;建立打开文件失败

             ret

       .endif

       mov     ByteOffset.HighPart,0

       mov     ByteOffset.LowPart,0

       invoke ZwWriteFile,File_Handle,NULL,NULL,NULL,addr Status,addr bmphd,36h,NULL,NULL

       mov     ByteOffset.LowPart,36h

       mov     esi,DataSize                                   ;每个象素点占4个字节,最后一个字节0,bmp不保存的.

       shr     esi,2                                         ;esi=有多少个象素

       mov     edi,DataSize

       sub     edi,esi                                       ;edi=BMP应该保存的字节数

       mov     BmpSize,edi

       invoke ZwWriteFile,File_Handle,NULL,NULL,NULL,addr Status,ScrnBuffer,BmpSize,addr ByteOffset,NULL

       invoke ZwClose,File_Handle

       invoke ExFreePool,ScrnBuffer                         ;释放分分配的保存显存数据的缓冲区

mov eax, 0

ret

DriverEntry endp

end DriverEntry

:make

set drv=DRRamScreen

..\bin\ml /nologo /c /coff %drv%.bat

..\bin\link /nologo /driver /base:0x10000 /align:32 /out:%drv%.sys /subsystem:native   %drv%.obj

del %drv%.obj

pause

 

你可能感兴趣的:(驱动)