文章目录
- 目的
- 操作步骤
- 逆向分析
- 实现代码
- 参考文献
目的
在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与ExpDisSetAttributeInformationULONG64 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");
}
参考文献
某超级注入程序的驱动逆向
火哥内核视频