内核上项目【通信】

目的

在Win7 64位系统上编写驱动利用ExRegisterAttributeInformationCallback注册回调进行通信

操作步骤

1.利用MmGetSystemRoutineAddress获取ExRegisterAttributeInformationCallback中ExpDisSetAttributeInformation、ExpDisQueryAttributeInformation全局变量位置,并将其置为0,以实现执行到注册的目标回调函数
2.三环部分利用NtQueryInformationFile进行通信,最后一项的FileInformationClass成员置为0x34以实现调用到0环注册的回调函数
3.在卸载驱动时将其原先保存的ExpDisQueryAttributeInformation、ExpDisSetAttributeInformation进行恢复,否则将蓝屏

逆向分析

箭头所标记位置进行判断全局变量ExpDisSetAttributeInformation、ExpDisQueryAttributeInformation是否为空,如果不为空就不进行注册,所以需要在操作步骤一中将其进行置0
在这里插入图片描述对ExpDisQueryAttributeInformation进行交叉引用发现其最终会通过NtQueryInformationFile进行调用
在这里插入图片描述NtQueryInformationFile中会判断成员FileInformationClass是否为0x34,如果不为0x34则不进行调用ExQueryAttributeInformation
在这里插入图片描述

实现代码

Win7_Comm.h(通信头文件)

#pragma once
#include<ntifs.h>
typedef struct _CommPackage
{
   
	ULONG64 Id;
	ULONG64 cmd;
	ULONG64 Data;
	ULONG64 Size;
	ULONG64 retStatus;
}CommPackage, * PCommPackage;

typedef NTSTATUS(*CommCallbackProc)(PCommPackage package);
typedef NTSTATUS(*FileCallBack)(HANDLE FileHandle, PVOID info);
typedef struct _RegisterCallback
{
   
	FileCallBack QueryFileCallback;
	FileCallBack SetFileCallBack;

}RegisterCallback, * PRegisterCallback;
typedef NTSTATUS(*ExRegisterAttributeInformationCallbackProc)(PRegisterCallback callbacks);

NTSTATUS CommWin7(CommCallbackProc callback);

VOID UnRegisterCommWin7();

VOID UnRegisterCommWin10();

VOID UnRegisterComm();

NTSTATUS SetFileCallBack(HANDLE FileHandle, PVOID info);

NTSTATUS QueryFileCallBack(HANDLE FileHandle, PVOID info);

Win7_Comm.c (通信实现代码)

#include"Win7_comm.h"

FileCallBack oldExpDisQueryAttributeInformationFunc = 0;
FileCallBack oldExpDisSetAttributeInformationFunc = 0;
CommCallbackProc gCommCallback = NULL;
PULONG64 gWin7CallbackVar = 0;

NTSTATUS QueryFileCallBack(HANDLE FileHandle, PVOID info)
{
   
	KdPrintEx((77, 0, "QueryFileCallBack\r\n"));
	if (MmIsAddressValid(info))
	{
   
		PCommPackage package = (PCommPackage)info;
		if (package->Id == 0x12345678)
		{
   
			package->retStatus = gCommCallback(package);

		}
		else
		{
   
			if (oldExpDisQueryAttributeInformationFunc)
			{
   
				return oldExpDisQueryAttributeInformationFunc(FileHandle, info);
			}
		}
	}


	return STATUS_SUCCESS;
}

NTSTATUS SetFileCallBack(HANDLE FileHandle, PVOID info)
{
   
	KdPrintEx((77, 0, "SetFileCallBack\r\n"));
	if (MmIsAddressValid(info))
	{
   
		PCommPackage package = (PCommPackage)info;
		if (package->Id == 0x12345678)
		{
   
			package->retStatus = gCommCallback(package);

		}
		else
		{
   
			if (oldExpDisSetAttributeInformationFunc)
			{
   
				return oldExpDisSetAttributeInformationFunc(FileHandle, info);
			}
		}

	}

	return STATUS_SUCCESS;
}

NTSTATUS CommWin7(CommCallbackProc callback)
{
   
	UNICODE_STRING unName = {
    0 };
	RtlInitUnicodeString(&unName, L"ExRegisterAttributeInformationCallback");
	ExRegisterAttributeInformationCallbackProc pFunc = MmGetSystemRoutineAddress(&unName);
	DbgBreakPoint();
	//寻找系统初始化的ExpDisQueryAttributeInformation与ExpDisSetAttributeInformation
	ULONG64 offset = *(PULONG)((ULONG64)pFunc + 0xD + 3);
	PULONG64 ExpDisQueryAttributeInformation = (offset + 0x14 + (ULONG64)pFunc);
	oldExpDisQueryAttributeInformationFunc = (FileCallBack)ExpDisQueryAttributeInformation[0];
	oldExpDisSetAttributeInformationFunc = (FileCallBack)ExpDisQueryAttributeInformation[1];

	ExpDisQueryAttributeInformation[0] = 0;
	ExpDisQueryAttributeInformation[1] = 0;
	RegisterCallback rcb = {
    0 };
	rcb.SetFileCallBack = SetFileCallBack;
	rcb.QueryFileCallback = QueryFileCallBack;

	NTSTATUS state = pFunc(&rcb);
	if (NT_SUCCESS(state))
	{
   
		gWin7CallbackVar = ExpDisQueryAttributeInformation;
		gCommCallback = callback;
	}
	return state;
}

VOID UnRegisterCommWin7()
{
   
	if (gWin7CallbackVar)
	{
   
		gWin7CallbackVar[0] = oldExpDisQueryAttributeInformationFunc;
		gWin7CallbackVar[1] = oldExpDisSetAttributeInformationFunc;
	}
}

VOID UnRegisterComm()
{
   
	RTL_OSVERSIONINFOEXW version = {
    0 };
	RtlGetVersion(&version);

	if (version.dwBuildNumber == 7600 || version.dwBuildNumber == 7601)
	{
   
		UnRegisterCommWin7();
		return;
	}
}

DriverMain.c (驱动主函数)

#include<ntifs.h>
#include"Win7_comm.h"

VOID DriverUnload(_In_ struct _DRIVER_OBJECT* DriverObject)
{
   
	DbgPrint("--------------DRIVER_UNLOAD-----------------");
	UnRegisterComm();
}

NTSTATUS NTAPI DispatchComm(PCommPackage package)
{
   
	DbgPrintEx(77, 0, "[db]:%llx,%llx\r\n", package->Id, package->cmd);
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath)
{
   
	NTSTATUS state = CommWin7(DispatchComm);

	pDriverObject->DriverUnload = DriverUnload;

	return STATUS_SUCCESS;
}

通信三环程序.cpp (三环通信程序)

#include <stdio.h>
#include<windows.h>

typedef struct _IO_STATUS_BLOCK {
   
	union {
   
		ULONG Status;
		PVOID Pointer;
	};

	ULONG_PTR Information;
} IO_STATUS_BLOCK, * PIO_STATUS_BLOCK;

typedef struct _CommPackage
{
   
	ULONG64 Id; 
	ULONG64 cmd;
	ULONG64 Data;
	ULONG64 Size;
	ULONG64 retStatus;
}CommPackage, * PCommPackage;

typedef ULONG(WINAPI* NtQueryInformationFileProc)(
	__in HANDLE FileHandle,
	__out PIO_STATUS_BLOCK IoStatusBlock,
	__out_bcount(Length) PVOID FileInformation,
	__in ULONG Length,
	__in ULONG FileInformationClass);

int main()
{
   
	char a[] = "123";
	PUCHAR b = (PUCHAR)a;

	NtQueryInformationFileProc NtQueryInformationFile = (NtQueryInformationFileProc)GetProcAddress(GetModuleHandleA("ntdll"),"NtQueryInformationFile");
	if (NtQueryInformationFile == NULL)
	{
   
		printf("NtQueryInformationFile获取失败!\n");
		system("pause");
		return 0;
	}
	IO_STATUS_BLOCK is = {
    0 };
	char buf[0xFF] = {
    0 };
	PCommPackage package = (PCommPackage)buf;
	package->Id = 0x12345678;
	package->cmd = 1;

	HANDLE handle = CreateFileA("C:\\1.txt", FILE_ALL_ACCESS, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	system("pause");
	NtQueryInformationFile(handle, &is, buf, sizeof(buf), 0x34);
	CloseHandle(handle);
	system("pause");
}

参考文献

某超级注入程序的驱动逆向
火哥内核视频

相关推荐

  1. linux内核网络源码 链通知事件

    2023-12-13 02:54:03       8 阅读
  2. 深入理解Linux 内核 内存管理(

    2023-12-13 02:54:03       10 阅读
  3. 通过GIT将本地项目传到gitee

    2023-12-13 02:54:03       39 阅读
  4. 将本地项目通过git传到仓库

    2023-12-13 02:54:03       35 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-13 02:54:03       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-13 02:54:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-13 02:54:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-13 02:54:03       18 阅读

热门阅读

  1. 网络编程发送接受多案例

    2023-12-13 02:54:03       38 阅读
  2. C++学习笔记(十四)

    2023-12-13 02:54:03       35 阅读
  3. python 中Windows编程一些心得

    2023-12-13 02:54:03       44 阅读
  4. 【算法集训】基础数据结构:四、栈

    2023-12-13 02:54:03       44 阅读
  5. linux链表应用2

    2023-12-13 02:54:03       40 阅读
  6. 2.2运行时数据区域----2.2.3本地方法栈

    2023-12-13 02:54:03       36 阅读
  7. Linux中的iptables

    2023-12-13 02:54:03       32 阅读
  8. vue:this.reload()跟this.$router.replace的区别

    2023-12-13 02:54:03       44 阅读
  9. C语言L / 数据在内存中的存储

    2023-12-13 02:54:03       31 阅读
  10. c# 十进制整数格式化-(占位符,补齐)

    2023-12-13 02:54:03       46 阅读
  11. 申论笔记(思路技巧)

    2023-12-13 02:54:03       37 阅读
  12. 分享一个Pinia存储的数据持久化插件

    2023-12-13 02:54:03       37 阅读