美文网首页
驱动小程序1

驱动小程序1

作者: MagicalGuy | 来源:发表于2018-10-10 00:49 被阅读0次

    第一个驱动程序

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

    相关文章

      网友评论

          本文标题:驱动小程序1

          本文链接:https://www.haomeiwen.com/subject/gvbdaftx.html