发布于:2018-10-3 17:52 | 157748次阅读 作者: 外部投稿 | 原作者: 通化程序员
在游戏外挂和反外挂的对抗中 驱动有其重要的作用 但是随着Windows 系统的升级 很多东西出现了局限性,不过我们还是需要了解学习一下 其最基础的知识
创建驱动设备对象的符号链接
//环境设置: //属性页->C / C++->警告等级 : 等级3 / W3 //属性页->C / C++->将警告视为错误 : 否 / WX - //属性页->Inf2Cat->Run Inf2Cat : 否 //属性页->Driver Settings->Target Os Version : 设置版本 Windows 7 Windows 10任选 //属性页->Driver Settings->Target PlatForm : Desktop //属性页->StampInf->Endable ArchiteCture : 否
//KdPrint类似于 控制台的printf //DriverEntry类似于 C / C++里的main
#include
#pragma code_seg("PAGE") //创建驱动设备对象 NTSTATUS CreateDevice(PDRIVER_OBJECT driver) { NTSTATUS status; UNICODE_STRING uzDriverName; PDEVICE_OBJECT device; RtlInitUnicodeString(&uzDriverName, L"\\DEVICE\\uzDriverName001"); //创建驱动设备 status = IoCreateDevice(driver, sizeof(driver->DriverExtension), &uzDriverName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &device);
if (status == STATUS_SUCCESS) { KdPrint(("yjx:驱动设备对象 %wZ 创建成功,OK -----------\n", &uzDriverName)); //为设备对象绑定一个符号链接 UNICODE_STRING uzSymbolName; //符号链接名字 RtlInitUnicodeString(&uzSymbolName, L"\\??\\uzDriverName001"); //CreateFile status = IoCreateSymbolicLink(&uzSymbolName, &uzDriverName); if (status==STATUS_SUCCESS) { KdPrint(("yjx:创建符号链接 %wZ 成功 ", &uzSymbolName)); } else { KdPrint(("yjx:创建符号链接 %wZ 失败 ", &uzSymbolName)); } } else {
KdPrint(("yjx:驱动设备对象 %wZ 创建失败,准备删除Device -----------\n", &uzDriverName)); IoDeleteDevice(device); } return status; } //驱动卸载例程 void UnLoad(PDRIVER_OBJECT driver) { NTSTATUS status = 0; IoDeleteDevice(driver->DeviceObject); //删除设备对象,如果此处不删除 卸载不干净 再次用IoCreateDevice创建同名驱动 会蓝屏 //删除符号链接 UNICODE_STRING uzSymbolName; //符号链接名字 RtlInitUnicodeString(&uzSymbolName, L"\\??\\uzDriverName001"); status=IoDeleteSymbolicLink(&uzSymbolName); if (!status) //if(status == STATUS_SUCCESS) { KdPrint(("yjx:删除符号链接 %wZ 成功 ",&uzSymbolName)); } else { KdPrint(("yjx:删除符号链接 %wZ 失败 ", &uzSymbolName)); } KdPrint(("yjx:驱动卸载成功\n")); }
NTSTATUS DriverEntry(PDRIVER_OBJECT driver,PVOID szReg) //main { KdPrint(("yjx:进入了我们的驱动 \n")); //printf driver->DriverUnload = UnLoad; NTSTATUS status=CreateDevice(driver);//创建了设备对象
return STATUS_SUCCESS; }
IRP 派遣函数
driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceIrpCtl;//DeviceIoControl driver->MajorFunction[IRP_MJ_CREATE] = DeviceIrpCtl; //CreateFile driver->MajorFunction[IRP_MJ_CLOSE] = DeviceIrpCtl;//卸载驱动 CloseHandle
NTSTATUS DeviceIrpCtl(PDEVICE_OBJECT device,PIRP pirp) { KdPrint(("yjx:进入派遣函数")); PIO_STACK_LOCATION irpStackL; ULONG CtlCode; ULONG InputBuffLength;
irpStackL=IoGetCurrentIrpStackLocation(pirp); //获取应用层传来的参数 switch(irpStackL->MajorFunction) { IRP_MJ_DEVICE_CONTROL; IRP_MJ_CREATE; IRP_MJ_CLOSE; }
pirp->IoStatus.Status = STATUS_SUCCESS; pirp->IoStatus.Information = 4;//返回给DeviceIoControl中的 倒数第二个参数lpBytesReturned IoCompleteRequest(pirp, IO_NO_INCREMENT);//调用方已完成所有I/O请求处理操作 并且不增加优先级 KdPrint(("yjx:离开派遣函数")); return STATUS_SUCCESS; }
//打开驱动设备 void CIoControlIrpDlg::OnBnClickedCreate() { // TODO: 在此添加控件通知处理程序代码 DeviceHandle = CreateFileW( L"\\??\\uzDriverName001", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
}
void CIoControlIrpDlg::OnBnClickedButtonClose() { // TODO: 在此添加控件通知处理程序代码 if (DeviceHandle) { CloseHandle(DeviceHandle); DeviceHandle = NULL; } }
R3应用层与R0驱动层简单通信
#define IO_IS_OK_TEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_BUFFERED,FILE_ANY_ACCESS) //测试
//WriteFile ReadFile BOOL DeviceIoControl( HANDLE hDevice, // 设备驱动的句柄 由CreateFile获取 DWORD dwIoControlCode, // 操作控制码 LPVOID lpInBuffer, // 输入缓冲区指针 要传入驱动的 参数 DWORD nInBufferSize, // 输入缓冲区大小 LPVOID lpOutBuffer, // 输出缓冲区指针 DWORD nOutBufferSize, // 输出缓冲区大小 LPDWORD lpBytesReturned, // 存放返回的字节数的指针 LPOVERLAPPED lpOverlapped // 异步结构指针,同步或者异步 );
BOOL WINAPI IoControlIsOK() { DWORD nTypeCode = IO_IS_OK_TEST; ULONG64 BufferInData = 0;; DWORD NumberOfBytesRead = 0; BOOL IsOK = DeviceIoControl( GetDeviceHandle(), //CreateFile函数打开的设备句柄 nTypeCode,//自定义的控制码 &BufferInData,//输入缓冲区 sizeof(BufferInData),//输入缓冲区大小 &BufferInData,////输出缓冲区 sizeof(BufferInData),//输出缓冲区的大小 &NumberOfBytesRead,//实际返回的字节数,对应驱动程序中pIrp->IoStatus.Information。 NULL); ////重叠操作结构指针。同步设为NULL,DeviceIoControl将进行阻塞调用;否则,应在编程时按异步操作设计 DbgPrintA("yjx:IsOK=%d,NumberOfBytesRead=%d BufferInData=%d", IsOK, NumberOfBytesRead, BufferInData); return NumberOfBytesRead; }
#include #define IO_IS_OK_TEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_BUFFERED,FILE_ANY_ACCESS) //测试 void CMFCIRPCTRLDlg::OnBnClickedButtonIoCtl() { // TODO: 在此添加控件通知处理程序代码 INT64 InBuf[3] = { 0x123456,0x123456789ABCDEF,0x888888ABC }; //输入缓冲区 INT64 OutBuf[6] = { 0 }; DWORD dwSize = 0; DeviceIoControl( DeviceHandle, IO_IS_OK_TEST, InBuf,//输入缓冲区指针 sizeof(InBuf),//2*8,//输入缓冲区大小 OutBuf,//输出缓冲区 sizeof(OutBuf), //输出缓冲区大小 6*8 =48 &dwSize,//返回 字节数 pIrp->IoStatus.Information //IRP.IOStatus.InforMation NULL //同步异步 ); CString csStr; csStr.Format(L"yjx:EXE:%llx,%llx,%llx,%llx,%llx,%llx dwSize=%llx .....OK\n", OutBuf[0], OutBuf[1], OutBuf[2], OutBuf[3], OutBuf[4], OutBuf[5], dwSize); OutputDebugStringW(csStr); }
//驱动层 获取用户层参数 Irp->AssociatedIrp.SystemBuffer; driver->Flags |= DO_BUFFERED_IO; //IO访问方式 重要 对应 METHOD_BUFFERED inBufLength = irpStack->Parameters.DeviceIoControl.InputBufferLength; outBufLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength; ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode; 来源:通化程序员—投稿 GSLAB网站投稿文章仅代表作者本人的观点,与本网站立场无关。 *转载请注明来自游戏安全实验室(GSLAB.QQ.COM) |
最新评论
发表评论