内核驱动开发---C#不需要管理员权限与驱动通信(part2)
张静茹2015/07/19软件综合 IP:天津
帖子中的驱动程序来自<寒江独钓>Windows内核安全编程和<windows内核安全与驱动开发>中应用与内核通信


驱动代码
<code class="lang-cpp">#include "DriverEntry.h"
 
//#define CWK_CDO_SYB_NAME L"\\??\\slbkcdo_3948f33e"//符号链接名
#define CWK_CDO_SYB_NAME L"\\DosDevices\\KeyFilterSyb"//符号链接名
#define DEVICE_NAME      L"\\Device\\KeyFilterDEVICE_NAME"//设备名
#define CTL_COD_STR (ULONG)CTL_CODE(FILE_DEVICE_UNKNOWN,0x912,              METHOD_BUFFERED,FILE_ALL_ACCESS)
                                //设备类型:未知类型     功能号[0x7ff,0xfff]    缓冲模式:缓冲 权限:全部
 
// {A79F4848-B37A-43C2-966B-E7A729CB44C7}
static const GUID SLBKGUID_CLASS_MYCDO =
{ 0xa79f4848, 0xb37a, 0x43c2, { 0x96, 0x6b, 0xe7, 0xa7, 0x29, 0xcb, 0x44, 0xc7 } };
 
 
//设备指针
PDEVICE_OBJECT g_cdo = NULL;
static KEVENT Event; //同步事件
 
//#pragma INITCODE
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,
    IN PUNICODE_STRING pRegistryPath)
{
    _asm_3
 
    //pDriverObject->DriverExtension->AddDevice = ;       //添加设备
    pDriverObject->DriverUnload = DriverUnload;
    pDriverObject->MajorFunction[IRP_MJ_CREATE] = Device_Create;     //创建
    pDriverObject->MajorFunction[IRP_MJ_CLOSE] = Device_Close;       //关闭
    pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Device_Conteol;//设备控制
    pDriverObject->MajorFunction[IRP_MJ_READ] = Device_Read;     //读
    pDriverObject->MajorFunction[IRP_MJ_WRITE] = Device_Write;   //写
    /*设置回调函数*/
 
    NTSTATUS status;
    UNICODE_STRING sddl = RTL_CONSTANT_STRING(L"D:P(A;;GA;;;WD)");
    UNICODE_STRING cdo_name = RTL_CONSTANT_STRING(DEVICE_NAME);
 
    if (g_cdo == NULL)
    {
        status = IoCreateDeviceSecure(//创建一个可以与应用通信的设备
            pDriverObject,  //生成此驱动对象的设备
            0,              //设备扩展大小
            &cdo_name,      //设备名
            FILE_DEVICE_UNKNOWN,    //设备类型:文件设备未知
            FILE_DEVICE_SECURE_OPEN,//设备特点
            FALSE,          //是否是一个独占设备
            &sddl,          //不需要 管理员权限     
            (LPCGUID)&SLBKGUID_CLASS_MYCDO,//GUID
            &g_cdo          //指向创建的设备
            );
        if (!NT_SUCCESS(status))//如果出错
        {
            IoDeleteDevice(g_cdo);
            return status;
            DbgPrint("%s第%d行错误代码 = %d\t", __FILE__, __LINE__, status);
        }
        else
        {
            DbgPrint("g_cdo=%x", g_cdo);
        }
 
    }
    /*创建设备对象*/
 
    UNICODE_STRING symLinkName;//符号链接
    RtlInitUnicodeString(&symLinkName, CWK_CDO_SYB_NAME);
 
    status = IoCreateSymbolicLink(&symLinkName, &cdo_name);//为设备名产生符号链接
    if (!NT_SUCCESS(status))//如果创建符号链接失败
    {
        DbgPrint("%s第%d行错误代码 = %d", __FILE__, __LINE__, status);
        IoDeleteSymbolicLink(&symLinkName);//如果错误就删除此符号链接
        status = IoCreateSymbolicLink(&symLinkName, &cdo_name);//再次为设备名产生符号链接
        if (!NT_SUCCESS(status))//如果还失败
        {
            DbgPrint("%s第%d行错误代码 = %d", __FILE__, __LINE__, status);
            IoDeleteDevice(g_cdo);//删除设备
            return  status;//返回错误码
        }
 
    }
 
    DbgPrint("%s初始化完毕 status= %d", __FILE__, status);
    KeInitializeEvent(&Event, SynchronizationEvent, FALSE);//初始化同步事件
    return STATUS_SUCCESS;
}
 
VOID DriverUnload(PDRIVER_OBJECT driver)
{
    //_asm_3;
    UNICODE_STRING symLinkName;//符号链接
    RtlInitUnicodeString(&symLinkName, CWK_CDO_SYB_NAME);
    NTSTATUS status = IoDeleteSymbolicLink(&symLinkName);//删除符号链接
    if (!NT_SUCCESS(status))
    {
 
    }
    if (g_cdo != NULL) 
        IoDeleteDevice(g_cdo);
    DbgPrint("%s%d卸载完毕", __FILE__, __LINE__);
}
 
NTSTATUS Device_Conteol(//设备控制
_In_ struct _DEVICE_OBJECT *DeviceObject,
_Inout_ struct _IRP *Irp)
{
    //_asm_3
        ASSERT(DeviceObject == g_cdo); //断言
    PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation(Irp);//获得当前Irp栈位置
    //IoGetCurrentProcess();//获得当前进程
 
    if (irpsp->Parameters.DeviceIoControl.IoControlCode == CTL_COD_STR)
    {
        NTSTATUS status = 0;
        //获取缓冲区
        PVOID buffer = Irp->AssociatedIrp.SystemBuffer;
        //获取缓冲区长度
        ULONG Inlength = irpsp->Parameters.DeviceIoControl.InputBufferLength;
        ULONG Outlength = irpsp->Parameters.DeviceIoControl.OutputBufferLength;
        //irpsp->Parameters.Write.Length;//写长度
        //irpsp->Parameters.Read.Length;//读长度
        //irpsp->Parameters.Read.Key;//
 
        ASSERT(Inlength > 0);
        ASSERT(buffer != NULL);
 
        RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, "返回数据", sizeof("返回数据")+1);//返回数据
 
    }
    Irp->IoStatus.Information = sizeof("返回数据") + 1;//实际返回字节数
    Irp->IoStatus.Status = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return 0;
}
 
 
 
 //下面的派遣函数 暂不处理
NTSTATUS Device_Read(//读
_In_ struct _DEVICE_OBJECT *DeviceObject,
_Inout_ struct _IRP *Irp)
{
    _asm_3
    Irp->IoStatus.Information = 0;
    Irp->IoStatus.Status = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return 0;
}
NTSTATUS Device_Write(//写
    _In_ struct _DEVICE_OBJECT *DeviceObject,
    _Inout_ struct _IRP *Irp)
{
    _asm_3
    KeSetEvent(&Event, 0, TRUE);
    Irp->IoStatus.Information = 0;
    Irp->IoStatus.Status = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return 0;
}
NTSTATUS Device_Create(//创建
    _In_ struct _DEVICE_OBJECT *DeviceObject,
    _Inout_ struct _IRP *Irp)
{
    //_asm_3
    Irp->IoStatus.Information = 0;
    Irp->IoStatus.Status = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return 0;
}
NTSTATUS Device_Close(//关闭
    _In_ struct _DEVICE_OBJECT *DeviceObject,
    _Inout_ struct _IRP *Irp)
{
    //_asm_3
    Irp->IoStatus.Information = 0;
    Irp->IoStatus.Status = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return 0;
}</code>



C++与驱动通信
<code class="lang-cpp">// 与sys通信.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <locale.h>
#define DEVICE_NAME L"\\\\.\\KeyFilterSyb"
#define CTL_COD_STR (ULONG)CTL_CODE(FILE_DEVICE_UNKNOWN,0x912,              METHOD_BUFFERED,FILE_ALL_ACCESS)
                                //设备类型:未知类型     功能号[0x7ff,0xfff]    缓冲模式:缓冲 权限:全部
 
int _tmain(int argc, _TCHAR* argv[])
{
    setlocale(LC_CTYPE, "");
    printf("功能号 = %x", CTL_COD_STR);
    getchar();
    HANDLE hDevice = CreateFile(
        DEVICE_NAME,             //设备路径
        GENERIC_ALL,             //访问模式(写 / 读)
        0,                       //共享模式 
        NULL,                    //指向安全属性的指针 
        OPEN_EXISTING,           //如何创建 
        FILE_ATTRIBUTE_NORMAL,   //文件属性 
        NULL);                   //用于复制文件句柄 
    printf("%s的第%d行:hDevice = %x,\tGetLastError = %d\n",__FILE__,__LINE__, hDevice, GetLastError());
    printf("任意键开始运行");
    getchar();
    char OutBuffer[30] = { 0 };
    char* InBuffer = "Hello World";
    DWORD size = 0;
 
    BOOL bol = DeviceIoControl(
        hDevice,        //设备指针
        CTL_COD_STR,    //控制功能号
        InBuffer,       //输入缓冲
        strlen(InBuffer) + 1,//缓冲大小
        OutBuffer,      //输出缓冲
        30,             //输出缓冲大小
        &size,          //实际输出数据的bytes
        NULL);          //用于异步输入输出消息的结构体//用于Overlapped操作
         
 
    printf("%s的第%d行:hDevice = %x,\tGetLastError = %d,bol=%d\n", __FILE__, __LINE__, hDevice, GetLastError(),bol);
 
    //printf("%s的第%d行:", __FILE__, __LINE__);
    printf("%s的第%d行:sizeof(L\"Hello World\")+1 = %d\n", __FILE__, __LINE__, sizeof("Hello World") + 1);
    printf("%s的第%d行:DeviceIoControl返回OutBuffer:%s\t实际输出大小%d\n", __FILE__, __LINE__,OutBuffer,size);
 
    //ReadFile(,,,,)
 
    CloseHandle(hDevice);
    printf("hDevice = %x,\tGetLastError = %d\n", hDevice, GetLastError());
    getchar();
    getchar();
    return 0;
}</locale.h></code>



C#与驱动通信

难点主要是封装C++的WinAPI
<code class="lang-c">namespace Csharp与sys通信
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        IntPtr hDevice;
        private void button__Click(object sender, EventArgs e)
        {
            DriverEntity.SECURITY_ATTRIBUTES a = new DriverEntity.SECURITY_ATTRIBUTES();
            hDevice = DriverDAL.CreateFile(
                "\\\\.\\KeyFilterSyb",
                DriverEntity.GENERIC_ALL,
                0,
                ref a,
                3,
                DriverEntity.FILE_ATTRIBUTE_NORMAL,
                IntPtr.Zero
                );
            label.Text = string.Format("hDevice = {0}\tGetLastError = {1} \r\na.lpSecurityDescriptor={2}\ta.nLength = {3}\r\na.bInheritHandl e= {4}", hDevice, DriverDAL.GetLastError(), a.lpSecurityDescriptor, a.nLength, a.bInheritHandle);
        }
 
        private void button_关闭设备_Click(object sender, EventArgs e)
        {
            DriverDAL.CloseHandle(hDevice);
        }
 
        private void button_IoControl_Click(object sender, EventArgs e)
        {
            byte[] InBuffer = System.Text.Encoding.Default.GetBytes("Hello_Csharp");
            byte[] OutBuffer = new byte[30];
            uint size = 0;
            DriverEntity.OVERLAPPED deo = new DriverEntity.OVERLAPPED();
 
            bool b = DriverDAL.DeviceIoControl(
                hDevice,
                0xc07fe448,
                InBuffer,
                (uint)InBuffer.Length,
                OutBuffer,
                (uint)OutBuffer.Length,
                ref size,
                ref deo
                );
            label.Text = string.Format("DeviceIoControl Return OutBuffer = {0}", System.Text.Encoding.Default.GetString(OutBuffer));
 
        }
        string DriverWrite(IntPtr hDevice, int ReturnLeng, params byte[] InBuffer)
        {
            byte[] OutBuffer = new byte[ReturnLeng];
            uint size = 0;
            DriverEntity.OVERLAPPED deo = new DriverEntity.OVERLAPPED();
 
            if(DriverDAL.DeviceIoControl(
                hDevice,
                0xc07fe448,
                InBuffer,
                (uint)InBuffer.Length,
                OutBuffer,
                (uint)OutBuffer.Length,
                ref size,
                ref deo))
            {
                return System.Text.Encoding.Default.GetString(OutBuffer);
            }
            else
            {
                return "";
            }
        }
 
        private void button_lock_Click(object sender, EventArgs e)
        {
            //new Thread(() => { 
                DriverWrite(hDevice, 0, 0x20);
                MessageBox.Show("解锁");
            //}).Start();
        }
 
        private void button_UnLock_Click(object sender, EventArgs e)
        {
            DriverWrite(hDevice, 0, 0x30);
 
        }
 
        private void button_Write_Click(object sender, EventArgs e)
        {
            byte[] Inbuff = new byte[0];
            uint i = 0;
            DriverEntity.OVERLAPPED a = new DriverEntity.OVERLAPPED();
            if (DriverDAL.WriteFile(
                hDevice,
                Inbuff,
                0,
                ref i,
                ref a))
            {
                label.Text = "True";
            }else
                label.Text = "Flase";
        }
    }
}</code>



来自:计算机科学 / 软件综合
2
已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也
sndnvaps
9年5个月前 IP:广东
780214
强烈围观。。。。。
虽然不知道是什么东西。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论

想参与大家的讨论?现在就 登录 或者 注册

所属专业
上级专业
同级专业
张静茹
进士 学者 机友 笔友
文章
139
回复
1869
学术分
1
2010/12/30注册,1个月26天前活动
暂无简介
主体类型:个人
所属领域:无
认证方式:手机号
IP归属地:未同步
文件下载
加载中...
{{errorInfo}}
{{downloadWarning}}
你在 {{downloadTime}} 下载过当前文件。
文件名称:{{resource.defaultFile.name}}
下载次数:{{resource.hits}}
上传用户:{{uploader.username}}
所需积分:{{costScores}},{{holdScores}}下载当前附件免费{{description}}
积分不足,去充值
文件已丢失

当前账号的附件下载数量限制如下:
时段 个数
{{f.startingTime}}点 - {{f.endTime}}点 {{f.fileCount}}
视频暂不能访问,请登录试试
仅供内部学术交流或培训使用,请先保存到本地。本内容不代表科创观点,未经原作者同意,请勿转载。
音频暂不能访问,请登录试试
支持的图片格式:jpg, jpeg, png
插入公式
评论控制
加载中...
文号:{{pid}}
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

加载中...
详情
详情
推送到专栏从专栏移除
设为匿名取消匿名
查看作者
回复
只看作者
加入收藏取消收藏
收藏
取消收藏
折叠回复
置顶取消置顶
评学术分
鼓励
设为精选取消精选
管理提醒
编辑
通过审核
评论控制
退修或删除
历史版本
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}