文号
t72674
阅读
5420
回复
2
收藏
2
内核驱动开发---C#不需要管理员权限与驱动通信(part2)
2015/07/19
IP:天津
帖子中的驱动程序来自<寒江独钓>Windows内核安全编程和<windows内核安全与驱动开发>中应用与内核通信


驱动代码
#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;
}



C++与驱动通信
// 与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>



C#与驱动通信

难点主要是封装C++的WinAPI
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";
        }
    }
}



11年5个月前IP:广东
780214
1楼
强烈围观。。。。。
虽然不知道是什么东西。
引用
评论
笔记
{{note.content}}
{{n.user.username}}
{{fromNow(n.toc)}} {{n.status === noteStatus.disabled ? "已屏蔽" : ""}} {{n.status === noteStatus.unknown ? "正在审核" : ""}} {{n.status === noteStatus.deleted ? '已删除' : ''}}
  • 编辑
  • 删除
  • {{n.status === 'disabled' ? "解除屏蔽" : "屏蔽" }}
我也是有底线的