逆向 | 驱动IRP通信模板
逆向 | 驱动IRP通信模板
踩了很多坑,比如说IoCreateDevice以后要删除,符号链接也要在卸载的时候删除啥的。
反正存个模板在这儿下次就能套了:
#include <ntddk.h>
#include <stdio.h>
#include <stdlib.h>
// 0-2047是保留的,可以用2048-4095
#define OPER1 CTL_CODE(FILE_DEVICE_UNKNOWN, 3001, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define OPER2 CTL_CODE(FILE_DEVICE_UNKNOWN, 3002, METHOD_BUFFERED, FILE_ANY_ACCESS)
PDEVICE_OBJECT g_pDeviceObj = NULL;
VOID DriverUnload(PDRIVER_OBJECT DriverObject) {
(DriverObject);
// 删除符号链接
UNICODE_STRING SymbolicLinkName;
RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\MyTestDriver");
IoDeleteSymbolicLink(&SymbolicLinkName);
// 删除设备
IoDeleteDevice(g_pDeviceObj);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "DriverUnload~\r\n");
}
NTSTATUS IrpCreateProc(PDEVICE_OBJECT pDevice, PIRP pIrp) {
(pDevice);
// 处理自己的业务
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[info] IrpCreateProc~\r\n");
// 设置返回状态
pIrp->IoStatus.Status = STATUS_SUCCESS; // getlasterror()
pIrp->IoStatus.Information = 0; // 返回给r3多少数据
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS IrpCloseProc(PDEVICE_OBJECT pDevice, PIRP pIrp) {
(pDevice);
// 处理自己的业务
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[info] IrpCloseProc~\r\n");
// 设置返回状态
pIrp->IoStatus.Status = STATUS_SUCCESS; // getlasterror()
pIrp->IoStatus.Information = 0; // 返回给r3多少数据
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS IrpDeviceProc(PDEVICE_OBJECT pDevice, PIRP pIrp) {
(pDevice);
// 处理自己的业务
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[info] IrpDeviceProc~\r\n");
NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
PIO_STACK_LOCATION pIrpStack;
ULONG uIoControlCode;
PVOID pIoBuffer;
ULONG uInLength;
ULONG uOutLength;
// 初始化输入输出缓冲区
UCHAR ReadBuf[1024] = { 0 };
UCHAR WriteBuf[] = "hello Mz1! ";
// 获取IRP数据
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
// 获取控制码
uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
// 获取缓冲区地址(输入和输出缓冲区都是一个)
pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;
// r3 发送数据的长度
uInLength = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
// r0 发送数据的长度
uOutLength = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
// 根据操作码决定操作
switch (uIoControlCode) {
case OPER1:
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[info] OPER1\r\n");
// 接收&输出数据
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, " 接收字节数: %d \r\n", uInLength);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, " 输出字节数: %d \r\n", uOutLength);
// read
memcpy(ReadBuf, pIoBuffer, uInLength);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, " recv: %s \r\n", ReadBuf);
// write
memcpy(pIoBuffer, WriteBuf, sizeof(WriteBuf));
// set status
pIrp->IoStatus.Information = sizeof(WriteBuf);
status = STATUS_SUCCESS;
break;
case OPER2:
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[info] OPER2\r\n");
pIrp->IoStatus.Information = 0;
status = STATUS_SUCCESS;
break;
}
// 设置返回状态
pIrp->IoStatus.Status = status; // getlasterror()
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
}
NTSTATUS DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
){
(RegistryPath);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "DriverEntry~\r\n");
DriverObject->DriverUnload = DriverUnload;
PDEVICE_OBJECT pDeviceObj = NULL;
// 创建设备对象名称,这个名字是给r0看的,要挂到树上
UNICODE_STRING Devicename;
RtlInitUnicodeString(&Devicename, L"\\Device\\MyDevice");
// 创建设备
NTSTATUS status = IoCreateDevice(
DriverObject, // 当前设备属于哪个驱动对象
0,
&Devicename, // 设备对象的名称
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&pDeviceObj // [out]设备对象指针
);
if (status != STATUS_SUCCESS) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[err] IoCreateDevice~\r\n");
return status;
}
g_pDeviceObj = pDeviceObj; // 复制一份全局对象
// 设置交互数据方式
pDeviceObj->Flags |= DO_BUFFERED_IO;
// 创建符号链接名称
UNICODE_STRING SymbolicLinkName;
// r3: CreateFile "\\\\.\\MyTestDriver"
RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\MyTestDriver");
// 创建符号链接
status = IoCreateSymbolicLink(&SymbolicLinkName, &Devicename);
if (status != STATUS_SUCCESS) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[err] IoCreateSymbolicLink~\r\n");
return status;
}
// 设置派遣函数
DriverObject->MajorFunction[IRP_MJ_CREATE] = IrpCreateProc;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = IrpCloseProc;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IrpDeviceProc;
return STATUS_SUCCESS;
}
r3部分:
// r3proj.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <Windows.h>
#include <winioctl.h>
// 0-2047是保留的,可以用2048-4095
#define OPER1 CTL_CODE(FILE_DEVICE_UNKNOWN, 3001, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define OPER2 CTL_CODE(FILE_DEVICE_UNKNOWN, 3002, METHOD_BUFFERED, FILE_ANY_ACCESS)
HANDLE g_hDevice;
DWORD IoControl(DWORD dwIoCode, PVOID InBuff, DWORD InBuffLen, PVOID OutBuff, DWORD OutBuffLen) {
DWORD dw = 0;
// 设备句柄/操作码/输入缓冲区地址/长度/输出缓冲区地址/输出缓冲区长度/返回长度/指向OVERLAPPED此处为NULL
DeviceIoControl(g_hDevice, dwIoCode, InBuff, InBuffLen, OutBuff, OutBuffLen, &dw, NULL);
return dw;
}
int main()
{
// 打开Device
// \\\\.\\MyTestDriver
g_hDevice = CreateFile(L"\\\\.\\MyTestDriver", GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
DWORD err = GetLastError();
printf("err: %d \n", err);
if (g_hDevice != INVALID_HANDLE_VALUE) {
printf("CreateFile ok \n");
}
else {
printf("error \n");
return -1;
}
// 测试通信
UCHAR InBuffer[1024] = "hihihihihihihihihihihihiashdasda";
UCHAR OutBuffer[1024] = { 0 };
DWORD ret = IoControl(OPER1, InBuffer, sizeof(InBuffer), OutBuffer, sizeof(OutBuffer));
printf("r3 recv[%d]: `%s` \n", ret, OutBuffer);
CloseHandle(g_hDevice);
printf("Over ok \n");
return 0;
}
本文来自博客园,作者:Mz1,转载请注明原文链接:https://www.cnblogs.com/Mz1-rc/p/18196603
如果有问题可以在下方评论或者email:mzi_mzi@163.com