第一个驱动程序
#include <ntddk.h>
VOID DriverUnload(PDRIVER_OBJECT pDriver)
{
pDriver;
}
NTSTATUS DriverEntry(
PDRIVER_OBJECT pDriver,//驱动对象
PUNICODE_STRING pPath //注册表路径
)
{
pPath;
_asm int 3;
int *p = 0;
*p = 100;
KdPrint(("Hello world"));
pDriver->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
======================
枚举驱动
#include <ntddk.h>
VOID DriverUnload(PDRIVER_OBJECT pDriver)
{
pDriver;
}
typedef struct _LDR_DATA_TABLE_ENTRY {
LIST_ENTRY InLoadOrderLinks; //双向链表
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
USHORT LoadCount;
USHORT TlsIndex;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
void EnumDirver(PDRIVER_OBJECT pDriver)
{
PLDR_DATA_TABLE_ENTRY pLdr =
(PLDR_DATA_TABLE_ENTRY)pDriver->DriverSection;
LIST_ENTRY *pTemp = &pLdr->InLoadOrderLinks;
do
{
PLDR_DATA_TABLE_ENTRY pDriverInfo =
(PLDR_DATA_TABLE_ENTRY)pTemp;
KdPrint(("%wZ\n", &pDriverInfo->FullDllName));
pTemp = pTemp->Blink;
} while (pTemp != &pLdr->InLoadOrderLinks);
}
IO_STACK_LOCATION
NTSTATUS DriverEntry(
PDRIVER_OBJECT pDriver,//驱动对象
PUNICODE_STRING pPath //注册表路径
)
{
pPath;
_asm int 3;
EnumDirver(pDriver);
KdPrint(("Hello world"));
pDriver->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
============================
Communication_ring0
#include <ntddk.h>
VOID DriverUnload(PDRIVER_OBJECT pDriver);
NTSTATUS DefaultProc(DEVICE_OBJECT *DeviceObject, IRP *Irp);
NTSTATUS ReadProc(DEVICE_OBJECT *objDeivce, IRP *pIrp);
NTSTATUS WriteProc(DEVICE_OBJECT *objDeivce, IRP *pIrp);
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pPath)
{
UNREFERENCED_PARAMETER(pPath);
KdPrint(("Enter Driver"));
DbgBreakPoint();
PDEVICE_OBJECT pDevice = NULL;
UNICODE_STRING strDeviceName;
UNICODE_STRING strSymbolicName;
RtlInitUnicodeString(&strDeviceName, L"\\Device\\Hello");
RtlInitUnicodeString(&strSymbolicName, L"\\DosDevices\\Hello");
//1 创建一个设备
IoCreateDevice(
pDriver, //驱动对象指针
0, //设备扩展大小,传0
&strDeviceName, //设备名称
FILE_DEVICE_UNKNOWN,//设备类型
0, //设备特征
FALSE, //设备是否独占
&pDevice //传出创建好的设备指针
);
//1.2 设置设备的读写方式
pDevice->Flags |= DO_BUFFERED_IO;//缓冲区读写方式
// |= DO_DIRECT_IO; //直接读写方式,使用MDL重映射报证安全
;
//2 给设备绑定一个符号链接
//设备名只能给内核层使用,在用户层想要访问设备,使用的是符号链接名
IoCreateSymbolicLink(&strSymbolicName, &strDeviceName);
//3 填写IRP处理函数
for (int i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
{
pDriver->MajorFunction[i] = DefaultProc;
}
pDriver->MajorFunction[IRP_MJ_READ] = ReadProc;
pDriver->MajorFunction[IRP_MJ_WRITE]= WriteProc;
pDriver->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
//在这个函数中写的是资源的清理
VOID DriverUnload(PDRIVER_OBJECT pDriver)
{
KdPrint(("Leave Driver"));
//1 删除符号链接
UNICODE_STRING strSymbolicName;
RtlInitUnicodeString(&strSymbolicName, L"\\DosDevices\\Hello");
IoDeleteSymbolicLink(&strSymbolicName);
//2 删除设备
IoDeleteDevice(pDriver->DeviceObject);
}
NTSTATUS DefaultProc(
DEVICE_OBJECT *objDeivce,
IRP *pIrp
)
{
UNREFERENCED_PARAMETER(objDeivce);
PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
switch (pStack->MajorFunction)//这个字段是IRP的类型码
{
case IRP_MJ_READ:
case IRP_MJ_WRITE:
//...
}
// 设置IRP完成状态
pIrp->IoStatus.Status = STATUS_SUCCESS;
// 设置IRP操作了多少字节
pIrp->IoStatus.Information = 0;
// 处理IRP
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS ReadProc(
DEVICE_OBJECT *objDeivce,
IRP *pIrp
)
{
UNREFERENCED_PARAMETER(objDeivce);
//获取缓冲区
UCHAR *buf = NULL;
if (pIrp->UserBuffer != NULL)
{
buf = pIrp->UserBuffer;
}
if (pIrp->AssociatedIrp.SystemBuffer != NULL)
{
buf = pIrp->AssociatedIrp.SystemBuffer;
}
if (pIrp->MdlAddress != NULL)
{
buf = MmGetSystemAddressForMdlSafe(pIrp->MdlAddress, NormalPagePriority);
}
//向缓冲区中写数据
RtlCopyMemory(buf, L"Helloworld",20);
// 设置IRP完成状态
pIrp->IoStatus.Status = STATUS_SUCCESS;
// 设置IRP操作了多少字节
pIrp->IoStatus.Information = 20;
// 处理IRP
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS WriteProc(
DEVICE_OBJECT *objDeivce,
IRP *pIrp
)
{
UNREFERENCED_PARAMETER(objDeivce);
UCHAR *buf=NULL;
//获得缓冲区大小
PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
ULONG uBufSize = pStack->Parameters.Write.Length;
//获取缓冲区
if (pIrp->UserBuffer!=NULL)
{
buf = pIrp->UserBuffer;
}
if (pIrp->AssociatedIrp.SystemBuffer!=NULL)
{
buf = pIrp->AssociatedIrp.SystemBuffer;
}
if (pIrp->MdlAddress!=NULL)
{
buf = MmGetSystemAddressForMdlSafe(pIrp->MdlAddress, NormalPagePriority);
}
KdPrint(("%S", buf));
// 设置IRP完成状态
pIrp->IoStatus.Status = STATUS_SUCCESS;
// 设置IRP操作了多少字节
pIrp->IoStatus.Information = 0;
// 处理IRP
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
====================
文件操作
#include <ntifs.h>
VOID DriverUnload(PDRIVER_OBJECT pDriver);
#define _countof(arr) sizeof(arr)/sizeof(arr[0])
//创建文件
HANDLE KernelCreateFile(
IN PUNICODE_STRING pstrFile, // 文件路径符号链接
IN BOOLEAN bIsDir) // 是否为文件夹
{
HANDLE hFile = NULL;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
IO_STATUS_BLOCK StatusBlock = { 0 };
ULONG ulShareAccess =
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
ULONG ulCreateOpt =
FILE_SYNCHRONOUS_IO_NONALERT;
// 1. 初始化OBJECT_ATTRIBUTES的内容
OBJECT_ATTRIBUTES objAttrib = { 0 };
ULONG ulAttributes =
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE;
InitializeObjectAttributes(
&objAttrib, // 返回初始化完毕的结构体
pstrFile, // 文件对象名称
ulAttributes, // 对象属性
NULL, NULL); // 一般为NULL
// 2. 创建文件对象
ulCreateOpt |= bIsDir ?
FILE_DIRECTORY_FILE : FILE_NON_DIRECTORY_FILE;
Status = ZwCreateFile(
&hFile, // 返回文件句柄
GENERIC_ALL, // 文件操作描述
&objAttrib, // OBJECT_ATTRIBUTES
&StatusBlock, // 接受函数的操作结果
0, // 初始文件大小
FILE_ATTRIBUTE_NORMAL, // 新建文件的属性
ulShareAccess, // 文件共享方式
FILE_OPEN_IF, // 文件存在则打开不存在则创建
ulCreateOpt, // 打开操作的附加标志位
NULL, // 扩展属性区
0); // 扩展属性区长度
if (!NT_SUCCESS(Status))
return (HANDLE)-1;
return hFile;
}
//获取文件大小
ULONG64 KernelGetFileSize(IN HANDLE hfile)
{
// 查询文件状态
IO_STATUS_BLOCK StatusBlock = { 0 };
FILE_STANDARD_INFORMATION fsi = { 0 };
NTSTATUS Status = STATUS_UNSUCCESSFUL;
Status = ZwQueryInformationFile(
hfile, // 文件句柄
&StatusBlock, // 接受函数的操作结果
&fsi, // 根据最后一个参数的类型输出相关信息
sizeof(FILE_STANDARD_INFORMATION),
FileStandardInformation);
if (!NT_SUCCESS(Status))
return 0;
return fsi.EndOfFile.QuadPart;
}
ULONG64 KernelReadFile(
IN HANDLE hfile, // 文件句柄
IN PLARGE_INTEGER Offset, // 从哪里开始读取
IN ULONG ulLength, // 读取多少字节
OUT PVOID pBuffer) // 保存数据的缓存
{
// 1. 读取文件
IO_STATUS_BLOCK StatusBlock = { 0 };
NTSTATUS Status = STATUS_UNSUCCESSFUL;
Status = ZwReadFile(
hfile, // 文件句柄
NULL, // 信号状态(一般为NULL)
NULL, NULL, // 保留
&StatusBlock, // 接受函数的操作结果
pBuffer, // 保存读取数据的缓存
ulLength, // 想要读取的长度
Offset, // 读取的起始偏移
NULL); // 一般为NULL
if (!NT_SUCCESS(Status)) return 0;
// 2. 返回实际读取的长度
return StatusBlock.Information;
}
ULONG64 KernelWriteFile(
IN HANDLE hfile, // 文件句柄
IN PLARGE_INTEGER Offset, // 从哪里开始写入
IN ULONG ulLength, // 写入多少字节
IN PVOID pBuffer) // 欲写入的数据
{
// 1. 写入文件
IO_STATUS_BLOCK StatusBlock = { 0 };
NTSTATUS Status = STATUS_UNSUCCESSFUL;
Status = ZwWriteFile(
hfile, // 文件句柄
NULL, // 信号状态(一般为NULL)
NULL, NULL, // 保留
&StatusBlock, // 接受函数的操作结果
pBuffer, // 欲写入的数据
ulLength, // 想要写入的长度
Offset, // 写入的起始偏移
NULL); // 一般为NULL
if (!NT_SUCCESS(Status)) return 0;
// 2. 返回实际写入的长度
// 2. 返回实际写入的长度
return StatusBlock.Information;
}
NTSTATUS KernelDeleteFile(IN PUNICODE_STRING pstrFile)
{
// 1. 初始化OBJECT_ATTRIBUTES的内容
OBJECT_ATTRIBUTES objAttrib = { 0 };
ULONG ulAttributes =
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE;
InitializeObjectAttributes(
&objAttrib, // 返回初始化完毕的结构体
pstrFile, // 文件对象名称
ulAttributes, // 对象属性
NULL, // 根目录(一般为NULL)
NULL); // 安全属性(一般为NULL)
// 2. 删除指定文件/文件夹
return ZwDeleteFile(&objAttrib);
}
VOID ZwMyCopyFile(
PUNICODE_STRING SouPath,//源地址
PUNICODE_STRING DenPath //目的地址
)
{
//1 打开源地址文件
HANDLE hSorHandle = KernelCreateFile(SouPath, FALSE);
//2 获取大小
ULONG64 FileSize = KernelGetFileSize(hSorHandle);
//3 申请空间,读取数据
PVOID buf = ExAllocatePool(NonPagedPool, (SIZE_T)FileSize);
RtlZeroMemory(buf, (SIZE_T)FileSize);
LARGE_INTEGER Offset = {0,0};
KernelReadFile(hSorHandle, &Offset, (SIZE_T)FileSize, buf);
//4 打开目的地址文件
HANDLE hDenHandle = KernelCreateFile(DenPath, FALSE);
//5 写入数据
KernelWriteFile(hDenHandle, &Offset, (SIZE_T)FileSize, buf);
//6 关闭句柄
ZwClose(hSorHandle);
ZwClose(hDenHandle);
}
BOOLEAN KernelFindFirstFile(
IN HANDLE hFile, // 文件句柄
IN ULONG ulLen, // 信息长度
OUT PFILE_BOTH_DIR_INFORMATION pDir, // 文件信息
IN ULONG uFirstlLen, // 信息长度
OUT PFILE_BOTH_DIR_INFORMATION pFirstDir // 第一个文件信息
) {
NTSTATUS Status = STATUS_UNSUCCESSFUL;
IO_STATUS_BLOCK StatusBlock = { 0 };
// 1. 获取第一个文件信息,看是否成功
Status = ZwQueryDirectoryFile(
hFile, NULL, NULL, NULL,// 文件句柄
&StatusBlock, // 接受函数的操作结果
pFirstDir, // 文件信息
uFirstlLen, // “文件信息“的数据长度
FileBothDirectoryInformation, // 查询模式
TRUE, // 是否返回一条起始信息
NULL, // 文件句柄指向的文件(一般为NULL)
FALSE); // 是否从目录开始的第一项扫描
// 2. 若成功,则获取文件列表
if (NT_SUCCESS(Status) == FALSE) {
return FALSE;
}
Status = ZwQueryDirectoryFile(
hFile, NULL, NULL, NULL,// 文件句柄
&StatusBlock, // 接受函数的操作结果
pDir, // 文件信息
ulLen, // “文件信息“的数据长度
FileBothDirectoryInformation, // 查询模式
FALSE, // 是否返回一条起始信息
NULL, // 文件句柄指向的文件(一般为NULL)
FALSE); // 是否从目录开始的第一项扫描
return NT_SUCCESS(Status);
}
BOOLEAN KernelFindNextFile(
IN PFILE_BOTH_DIR_INFORMATION pDirList,//
OUT PFILE_BOTH_DIR_INFORMATION pDirInfo,
IN OUT LONG * Loc) {
// 如果有下一项,则移动指针指向下一项
PFILE_BOTH_DIR_INFORMATION pDir = (PFILE_BOTH_DIR_INFORMATION)((PCHAR)pDirList + *Loc);
LONG StructLenth = 0;
if (pDir->FileName[0] != 0)
{
StructLenth = sizeof(FILE_BOTH_DIR_INFORMATION);
memcpy(pDirInfo, pDir, StructLenth + pDir->FileNameLength);
*Loc = *Loc + pDir->NextEntryOffset;
if (pDir->NextEntryOffset == 0) {
*Loc = *Loc + StructLenth + pDir->FileNameLength;
}
return TRUE;
}
return FALSE;
}
NTSTATUS EnmuFile()
{
UNICODE_STRING ustrFolder = { 0 };
WCHAR szSymbol[0x512] = L"\\??\\";
UNICODE_STRING ustrPath =
RTL_CONSTANT_STRING(L"C:\\");
HANDLE hFile = NULL;
SIZE_T nFileInfoSize =
sizeof(FILE_BOTH_DIR_INFORMATION) + 270 * sizeof(WCHAR);
SIZE_T nSize = nFileInfoSize * 0x256; //假设最多有0x256个文件
char strFileName[0x256] = { 0 };
PFILE_BOTH_DIR_INFORMATION pFileTemp = NULL;
PFILE_BOTH_DIR_INFORMATION pFileList = NULL;
pFileList = (PFILE_BOTH_DIR_INFORMATION)ExAllocatePool(PagedPool, nSize);
pFileTemp = (PFILE_BOTH_DIR_INFORMATION)ExAllocatePool(PagedPool,
nFileInfoSize);
// 1. 将路径组装为连接符号名,并打开文件
wcscat_s(szSymbol, _countof(szSymbol), ustrPath.Buffer);
RtlInitUnicodeString(&ustrFolder, szSymbol);
hFile = KernelCreateFile(&ustrFolder, TRUE);
if (KernelFindFirstFile(hFile, nSize, pFileList, nFileInfoSize, pFileTemp))
{
LONG Loc = 0;
do
{
RtlZeroMemory(strFileName, 0x256);
RtlCopyMemory(strFileName,
pFileTemp->FileName,
pFileTemp->FileNameLength);
if (strcmp(strFileName, "..") == 0
|| strcmp(strFileName, ".") == 0)
continue;
if (pFileTemp->FileAttributes
& FILE_ATTRIBUTE_DIRECTORY)
DbgPrint("[目录]%S\n", strFileName);
else
DbgPrint("[文件]%S\n", strFileName);
memset(pFileTemp, 0, nFileInfoSize);
} while (KernelFindNextFile(pFileList, pFileTemp, &Loc));
}
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pPath)
{
UNREFERENCED_PARAMETER(pPath);
UNREFERENCED_PARAMETER(pDriver);
KdPrint(("Enter Driver"));
DbgBreakPoint();
//UNICODE_STRING SorPath;
//UNICODE_STRING DenPath;
//RtlInitUnicodeString(&SorPath, L"\\??\\D:\\test1\\123.txt");
//RtlInitUnicodeString(&DenPath, L"\\??\\D:\\Test2\\456.txt");
//ZwMyCopyFile(&SorPath, &DenPath);
EnmuFile();
return STATUS_SUCCESS;
}
//在这个函数中写的是资源的清理
VOID DriverUnload(PDRIVER_OBJECT pDriver)
{
UNREFERENCED_PARAMETER(pDriver);
KdPrint(("Leave Driver"));
}
=====================
进程操作
#include <ntifs.h>
VOID DriverUnload(PDRIVER_OBJECT pDriver);
// 1. 声明要使用此函数
NTKERNELAPI NTSTATUS PsSuspendProcess(PEPROCESS pEProcess);
// 根据PID返回进程EPROCESS,失败返回NULL
PEPROCESS LookupProcess(HANDLE hPid)
{
PEPROCESS pEProcess = NULL;
if (NT_SUCCESS(PsLookupProcessByProcessId(
hPid, &pEProcess)))
return pEProcess;
return NULL;
}
BOOLEAN KernelSuspendProcess(ULONG Id)
{
//1. 先根据ID得到EPORCESS
PEPROCESS pEProcess;
if ((pEProcess = LookupProcess((HANDLE)Id) )!= NULL)
{
//2. 暂停进程
if (NT_SUCCESS(PsSuspendProcess(pEProcess)))
return FALSE;
}
return TRUE;
}
NTKERNELAPI NTSTATUS PsResumeProcess(
PEPROCESS pEProcess);
BOOLEAN KernelResumeProcess(ULONG Id)
{
//1. 先根据ID得到EPORCESS
PEPROCESS pEProcess;
if ((pEProcess = LookupProcess((HANDLE)Id)) != NULL)
{
//2. 暂停进程
if (NT_SUCCESS(PsResumeProcess(pEProcess)))
return FALSE;
}
return TRUE;
}
void KernelKillProcess() {
HANDLE hProcess = NULL;
CLIENT_ID ClientId = { 0 };
OBJECT_ATTRIBUTES objAttribut =
{ sizeof(OBJECT_ATTRIBUTES) };
ClientId.UniqueProcess = (HANDLE)1234; // PID
ClientId.UniqueThread = 0;
// 打开进程,如果句柄有效,则结束进程
ZwOpenProcess(
&hProcess, // 返回打开后的句柄
1, // 访问权限
&objAttribut, // 对象属性
&ClientId); // 进程ID结构
if (hProcess) {
ZwTerminateProcess(hProcess, 0);
ZwClose(hProcess);
};
}
NTKERNELAPI HANDLE PsGetProcessInheritedFromUniqueProcessId(
IN PEPROCESS pEProcess);
NTKERNELAPI UCHAR* PsGetProcessImageFileName(
IN PEPROCESS pEProcess);
VOID EnumProcess() {
PEPROCESS pEProc = NULL;
// 循环遍历进程(假设线程的最大值不超过0x25600)
ULONG i = 0;
for (i = 4; i<0x25600; i = i + 4) {
// a.根据PID返回PEPROCESS
pEProc = LookupProcess((HANDLE)i);
if (!pEProc) continue;
// b. 打印进程信息
DbgPrint("EPROCESS=%p PID=%ld PPID=%ld Name=%s\n",
pEProc, (UINT32)PsGetProcessId(pEProc),
(UINT32)PsGetProcessInheritedFromUniqueProcessId(pEProc),
PsGetProcessImageFileName(pEProc));
// c. 将进程对象引用计数减1
ObDereferenceObject(pEProc);
DbgPrint("\n");
}
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pPath)
{
UNREFERENCED_PARAMETER(pPath);
UNREFERENCED_PARAMETER(pDriver);
KdPrint(("Enter Driver"));
DbgBreakPoint();
//KernelSuspendProcess(3364);
EnumProcess();
pDriver->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
//在这个函数中写的是资源的清理
VOID DriverUnload(PDRIVER_OBJECT pDriver)
{
UNREFERENCED_PARAMETER(pDriver);
KdPrint(("Leave Driver"));
//KernelResumeProcess(3364);
}
网友评论