• 用驱动直接显存抓屏


     ;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
  • 相关阅读:
    select和epoll的区别
    Epoll导致的selector空轮询
    2.集合框架中的泛型有什么优点?
    java的语法基础(二)
    17-文本属性和字体属性
    15-浮动
    16-margin的用法
    14-块级元素和行内元素
    12-简单认识下margin
    day15 什么是递归/递归与回溯
  • 原文地址:https://www.cnblogs.com/qintangtao/p/2918059.html
Copyright © 2020-2023  润新知