内核安全编程(一)共享内存
来源:互联网 发布:2017 天使投资数据 编辑:程序博客网 时间:2024/06/06 13:18
前面分别通过读写驱动(IRP)和IO控制(ControlCOde)两种方法来实现ring3和ring0的通信,今天学习共享内存通信方法
共享内存实现有两种方式:
1.应用程序分配内存,提供给驱动程序,由驱动程序映射并锁定该内存。
2.驱动程序分配内存,然后映射到应用程序地址范围内。
这里主要学习按书上的第二种方法的实现。
步骤:
1.驱动程序分配出一块内核空间。
2.使用MDL描述这篇内存并锁定内存,映射的用户空间。
3.将映射到用户空间的地址交给应用程序,然后由应用程序操作该地址内存空间。
代码如下:
1.首先添加一个IO_CODE用来处理共享内存的分配:
#define IOCTL_SHARE_MEMORY\CTL_CODE(FILE_DEVICE_UNKNOWN,0x893,METHOD_BUFFERED,FILE_ANY_ACCESS)
2.处理该共享内存的case分支如下:(前面的代码可参考之前的博客)
case IOCTL_SHARE_MEMORY:pOutBuf=Irp->AssociatedIrp.SystemBuffer;//pUseBuf=Irp->UserBuffer;这里获取用户空间地址(即IOControl函数的输入buf在ring3的地址)//KdPrint(("IOCTL_SHARE_MEMOEY SysbBuf:0x%08x UserBuf:0x%08x\n",pOutBuf,pUseBuf));pSysAddr=DeviceObject->DeviceExtension;//将DeviceExtension做为要共享的内存pMDL=IoAllocateMdl(pSysAddr,10,FALSE,FALSE,NULL);//分配MDL描述内核空间if(NULL==pMDL){KdPrint(("IOCTL_SHARE_MEMORY False!\n"));status=STATUS_UNSUCCESSFUL;break;}MmBuildMdlForNonPagedPool(pMDL);//锁定该内核空间*(ULONG *)pOutBuf=(ULONG)MmMapLockedPagesSpecifyCache(pMDL,UserMode,MmNonCached,NULL,FALSE,NormalPagePriority);//映射内存if(NULL==*(ULONG *)pOutBuf){KdPrint(("IOCTL_SHARE_MEMORY False MmMapLocked...\n"));status=STATUS_UNSUCCESSFUL;IoFreeMdl(pMDL);break;}KdPrint(("IOCTL_SHARE_MEMOEY SysbBuf:0x%08x UserBuf:0x%08x\n",pSysAddr,*(DWORD *)pOutBuf));break;
有一些需要学习的:
1.ring3在调用DeviceIoControl时的输入参数:
BOOL WINAPI DeviceIoControl( _In_ HANDLE hDevice, _In_ DWORD dwIoControlCode, _In_opt_ LPVOID lpInBuffer, _In_ DWORD nInBufferSize, _Out_opt_ LPVOID lpOutBuffer, _In_ DWORD nOutBufferSize, _Out_opt_ LPDWORD lpBytesReturned, _Inout_opt_ LPOVERLAPPED lpOverlapped);
lpOutBuffer在ring3层的地址在传递到ring0后保存在Irp->UserBuffer中。而IRP->AssociatedIrp.SystemBuffer实际是该参数在ring0的映射,当处理完Irp时就会将这块内存的数据拷贝到Irp->UserBuffer中。
2.*(DWORD *)pOutBuf=(DWORD)MmMapLockedPagesSpecifyCache
这句代码是将MmMapLockedPagesSpecifyCache返回的地址写入pOutBuf指向的内存空间,即“指针的指针”
换句话说,即poutBuf作为输出的指针,其内存中保存的是一个地址,这个地址指向了我们的共享内存。
(DWORD *)pOutBuf说明我们的pOutBuf指向的是一个DWORD类型的指针,然后再在前面加上"*",说明这个DWORD也是一个地址,而这个DWORD指向的地址就是共享内存的地址,即后面的赋值语句。
还可以通过一段程序来验证:
#include "stdafx.h"#include "windows.h"int _tmain(int argc, _TCHAR* argv[]){int a=8;PVOID p=&a;DWORD x=0x00123456;*(DWORD *)p=x;}
3.测试代码及结果如下:
首先通过IOCTL_BUFFERED_IO写入Hello World到扩展空间,然后发送IOCTL_SHARE_MEMORY将扩展空间作为共享内存并map到ring3,这样在ring0写入的"LL LOVE U"数据也相当于在ring3写入了数据。
#include "windows.h"#include "winioctl.h"#include "stdio.h"#define IOCTL_BUFFERED_IO CTL_CODE(FILE_DEVICE_UNKNOWN,0x890,METHOD_BUFFERED,FILE_ANY_ACCESS)#define IOCTL_SHARE_MEMORY CTL_CODE(FILE_DEVICE_UNKNOWN,0x893,METHOD_BUFFERED,FILE_ANY_ACCESS)int main(){HANDLE hFile=CreateFileA("\\\\.\\DriverCtr0",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);if(hFile==INVALID_HANDLE_VALUE) { printf("CreateFile Flase :%d\n",GetLastError()); return 0; } BYTE * pShareAddr;DWORD dwRet=0;int bRet=0;bRet=DeviceIoControl(hFile,IOCTL_BUFFERED_IO,"Hello World",10,NULL,20,&dwRet,NULL);if(!bRet){ printf("DeviceIoControl False : %d\n",GetLastError());CloseHandle(hFile);return 0;}bRet=DeviceIoControl(hFile,IOCTL_SHARE_MEMORY,NULL,0,&pShareAddr,4,&dwRet,NULL);if(!bRet){printf("DeviceIoControl False : %d\n",GetLastError());CloseHandle(hFile);}printf("DeviceIoControl IOCTL_SHARE_MEMORY pShareAddr:0x%08x ShareData:%s\n",pShareAddr,pShareAddr);bRet=DeviceIoControl(hFile,IOCTL_BUFFERED_IO,"LL Love U",10,NULL,20,&dwRet,NULL);if(!bRet){ printf("DeviceIoControl False : %d\n",GetLastError());CloseHandle(hFile);return 0;}printf("ShareMemory:%s\n",pShareAddr);CloseHandle(hFile);}
- 内核安全编程(一)共享内存
- 用户态和内核共享内存编程
- 内核安全编程(一)IO控制驱动程序
- 内核安全编程(一)读写驱动程序1.1
- 内核安全编程(一)读写驱动程序1.2
- <寒江独钓>Windows内核安全编程__键盘过滤之内核级Hook(一)
- Windows内核安全编程__键盘过滤之内核级Hook(一)
- 并发编程原则与技术(二)——内存可见性与共享对象安全访问方式
- Linux环境编程之共享内存区(一):共享内存区简介
- Linux编程练习(一)—— 多线程+共享内存+线程信号量练习
- Linux内核和用户空间通信的方式(一)— proc文件和mmap共享内存
- Linux内核和用户空间通信的方式(一)— proc文件和mmap共享内存
- Linux内核和用户空间通信的方式(一)— proc文件和mmap共享内存
- Linux内核和用户空间通信的方式(一)— proc文件和mmap共享内存
- Linux内核和用户空间通信的方式(一)— proc文件和mmap共享内存
- Linux内核和用户空间通信的方式(一)— proc文件和mmap共享内存
- Linux内核和用户空间通信的方式(一)— proc文件和mmap共享内存
- Linux 编程 共享内存
- Linux基础知识汇总
- web站点崩溃原因
- 第一篇关于ruby on rails安装问题的博客
- windows文件如何同步到linux
- css 介绍
- 内核安全编程(一)共享内存
- WGS84坐标转火星坐标(iOS篇)
- C++优先队列的基本使用方法
- 个人作品”可米录音机“上线啦,自己激动一下下
- Spring入门
- noip2013题解 普及组
- vsftpd配置只允许从某个主机访问
- HDU 3760 Ideal Path (bfs,分层)
- mysql 事务简介