0环代码
#include<ntifs.h>
//驱动对象名称
#define DRIVER_NAME L"\\driver\\NDIS"
//控制码起始地址
#define IRP_IOCTRLL_BASE 0x8000
//控制码的宏定义
#define IRP_IOCTRL_CODE(i) CTL_CODE(FILE_DEVICE_UNKNOWN,IRP_IOCTRLL_BASE+i,METHOD_BUFFERED,FILE_ANY_ACCESS)
//控制码定义
#define CTL_PRINT IRP_IOCTRL_CODE(0)
//保存原始的处理函数
PDRIVER_DISPATCH OldDriverFunction;
//由于ObReferenceObjectByName没有文档化,故在使用前先做声明:
//可以根据驱动名称可以得到PDRIVER_OBJECT,进而得到该驱动的PDEVICE_OBJECT。
extern POBJECT_TYPE* IoDriverObjectType;
NTSTATUS
ObReferenceObjectByName(
__in PUNICODE_STRING ObjectName,
__in ULONG Attributes,
__in_opt PACCESS_STATE AccessState,
__in_opt ACCESS_MASK DesiredAccess,
__in POBJECT_TYPE ObjectType,
__in KPROCESSOR_MODE AccessMode,
__inout_opt PVOID ParseContext,
__out PVOID* Object
);
VOID DriverUnload(PDRIVER_OBJECT pDriver) {
//设备名称
UNICODE_STRING uDrivername = { 0 };
//初始化设备名称
RtlInitUnicodeString(&uDrivername, DRIVER_NAME);
//什么驱动对象
PDRIVER_OBJECT pDriverObjeck = NULL;
//获取驱动对象->借壳通信
NTSTATUS ntSTATUS = ObReferenceObjectByName(&uDrivername, OBJ_CASE_INSENSITIVE, NULL, FILE_ALL_ACCESS, *IoDriverObjectType, KernelMode, NULL, &pDriverObjeck);
//对IRP_MJ_DEVICE_CONTROL进行恢复
pDriverObjeck->MajorFunction[IRP_MJ_DEVICE_CONTROL] = OldDriverFunction;
DbgPrint("Unload success!\n");
}
//IRP派遣函数-控制派遣
NTSTATUS DispatchIoCtrl(PDEVICE_OBJECT pDeviceObject, PIRP pIrp) {
//控制码
ULONG uIoCode = 0;
//输入缓冲区
PVOID pInputBuffer = NULL;
//输出缓冲区
PVOID pOutputBuffer = NULL;
//输入缓冲区的长度
ULONG uInputLength = 0;
//栈结构指针
PIO_STACK_LOCATION pStack = NULL;
//获取缓冲区
pInputBuffer = pOutputBuffer = pIrp->AssociatedIrp.SystemBuffer;
//获取IRP栈
pStack = IoGetCurrentIrpStackLocation(pIrp);
uInputLength = pStack->Parameters.DeviceIoControl.InputBufferLength;
//获取控制码
uIoCode = pStack->Parameters.DeviceIoControl.IoControlCode;
switch (uIoCode)
{
case CTL_PRINT:
{
DbgPrint("%s", pInputBuffer);
//初始化缓冲区内存
RtlZeroMemory(pOutputBuffer, 1024);
//获取字符串长度
ULONG uStringLength = strlen("IO Success whitebird");
//内存拷贝
RtlCopyMemory(pOutputBuffer, "IO Success whitebird", uStringLength);
//设置IRP处理成功,告诉3环
pIrp->IoStatus.Status = STATUS_SUCCESS;
//设置返回的字节数
pIrp->IoStatus.Information = uStringLength;
//结束IRP处理流程
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
if (pIrp->IoStatus.Status != 0)
{
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return OldDriverFunction(pDeviceObject, pIrp);
}
}
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath) {//驱动对象指针,注册表路径 DriverEntry不能改
//设备名称
UNICODE_STRING uDrivername = { 0 };
//初始化设备名称
RtlInitUnicodeString(&uDrivername, DRIVER_NAME);
//设置驱动对象
PDRIVER_OBJECT pDriverObjeck = NULL;
//获取驱动对象->借壳通信
NTSTATUS ntSTATUS=ObReferenceObjectByName(&uDrivername, OBJ_CASE_INSENSITIVE, NULL, FILE_ALL_ACCESS, *IoDriverObjectType, KernelMode, NULL, &pDriverObjeck);
if (!NT_SUCCESS(ntSTATUS))
{
DbgPrint("%x", ntSTATUS);
}
if (pDriverObjeck)
{
ObDereferenceObject(pDriverObjeck);//失败后关闭驱动对象引用
}
//保存原来IRP_MJ_DEVICE_CONTROL的功能
OldDriverFunction = pDriverObjeck->MajorFunction[IRP_MJ_DEVICE_CONTROL];
//将IRP_MJ_DEVICE_CONTROL跳到我们自己实现的函数功能上
pDriverObjeck->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoCtrl;
pDriverObject->DriverUnload = DriverUnload;
DbgPrint("Driver Load Success!");
return STATUS_SUCCESS;//状态成功0,一定要有返回值
}
3环代码
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<Windows.h>
#define LINK_NAME L"\\\\.\\NDIS"
//控制码起始地址
#define IRP_IOCTRLL_BASE 0x8000
//控制码的宏定义
#define IRP_IOCTRL_CODE(i) CTL_CODE(FILE_DEVICE_UNKNOWN,IRP_IOCTRLL_BASE+i,METHOD_BUFFERED,FILE_ANY_ACCESS)
//控制码定义
#define CTL_PRINT IRP_IOCTRL_CODE(0)
int main() {
//打开符号链接
HANDLE hDeviceHandle=CreateFile(LINK_NAME, GENERIC_ALL, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
//判断符号链接是否打开成功
if (hDeviceHandle==INVALID_HANDLE_VALUE)
{
printf("Error:%d\n",GetLastError);
system("pause");
return 0;
}
//IRP_MJ_DEVICE_CONTROL
while (1) {
char InputBuffer[1024] = { 0 };
char OutputBuffer[1024] = { 0 };
ULONG dwRet = 0;
printf("请输入字符串:\n");
scanf("%s", &InputBuffer);
DeviceIoControl(hDeviceHandle, CTL_PRINT, InputBuffer, sizeof(InputBuffer), OutputBuffer, sizeof(OutputBuffer), &dwRet, NULL);
printf("Return %d bytes\n", dwRet);
printf("%s\n", OutputBuffer);
}
return 0;
}
我们通过劫持系统中的驱动进行R0与R3的通信