驱动小程序1

第一个驱动程序

#include 

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 

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 
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 
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 
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);
}

你可能感兴趣的:(驱动小程序1)