首页
社区
课程
招聘
[旧帖] [原创]一个键位映射程序,r3控制+r0驱动,算是研究了10来天驱动的成果吧 0.00雪花
2010-3-9 01:27 3748

[旧帖] [原创]一个键位映射程序,r3控制+r0驱动,算是研究了10来天驱动的成果吧 0.00雪花

2010-3-9 01:27
3748
这是基于那个很有名的CTRL2CAP和寒江独钓里面的例子写出来的
添加了驱动的MajorFunction[IRP_MJ_DEVICE_CONTROL]和改进了一下原来的unload函数,最后不用按个键也可以卸载
映射是用传统的挂接过滤设备的方式来实现的

ring3部分用C#写的,调用win32api,建立服务,启动,DeviceIoControl通信,关闭等等
将记录下要映射的源键和目标键的扫描码发到驱动
首先要把服务安装和启动,基本的流程是
OpenSCManager  >> CreateService or OpenService >> StartService ,到这里就启动好了
然后要DeviceIoControl,基本流程~
CreateFile ~ DeviceIoControl  这样就可以通信r0了
但是CreateFile可能会遇到一些权限问题,因为是自己写的驱动,可以在CreateFile第二个参数写0,不需要要任何权限...反正没有权限也可以DeviceIoControl
最后记得要关掉从CreateFile拿来的句柄,不然没办法卸载和接受新的IO控制

于是于是,
经过无数次BOSD后她们终于跟操作系统和睦相处了
在32位XP和win7测试通过~
目前可以支持大概4块键盘(过段时间更新一下应该可以去掉这个限制),和最多映射9对键,当然这只是为了r3程序的布局好看而已..你可以随便添加的/

ring3ring0源码和binary都在附件
在这里估计C#很小众吧..而且我是用VS2010建的C#项目(更加没人用!)...
把C#关键代码段贴出来,源码不下也罢-w-

/*******************************************
/模块描述:KCC安装驱动和DeviceIoControl通信
/作者:葉月
/*******************************************
//下面开始使用Service系列API安装驱动
            //首先需要OpenSCManager拿到hSCManager
            IntPtr hSCManager = OpenSCManager(null, null, 0xF003F); //SC_MANAGER_ALL_ACCESS (0xF003F)
            if (hSCManager == IntPtr.Zero)
            {
                MessageBox.Show("OpenSCManager失败,Error Code:" + Marshal.GetLastWin32Error().ToString());
                return false;
            }

            //建立一个服务
            IntPtr hService;
            RegistryKey serviceKey = Registry.LocalMachine;            
            try
            {
                //在XP和win7下OpenSubKey对指定键值不存在的反应会不一样,XP会异常而win7不会,故当键值不存在时手动抛出一个异常
                //如果键值不存说明服务没有创建,进catch块建立服务
               
                if (serviceKey.OpenSubKey("SYSTEM", true).OpenSubKey("CurrentControlSet", true).OpenSubKey("services", true).OpenSubKey("kbdFilter", true) == null)
                {
                    throw new Exception();
                }
            }
            catch
            {
                hService = CreateService(
                    hSCManager,
                    "kbdFilter",
                    "kbdFilter",
                    0x0002,
                    0x00000001,
                    0x00000003,
                    0x00000001,
                    System.AppDomain.CurrentDomain.BaseDirectory + "kbdFilter.sys",        // path to service's binary
                    null,                      // no load ordering group
                    0,                         // no tag identifier
                    null,                      // no dependencies
                    null,                      // LocalSystem account
                    null);                     // no password
                if (hService == IntPtr.Zero && Marshal.GetLastWin32Error().ToString() != "1073")
                {
                    MessageBox.Show("CreateService失败,Error Code:" + Marshal.GetLastWin32Error().ToString());
                    return false;
                }
            
            }

            //打开服务
            hService = OpenService(
                hSCManager,         // SCM database
                "kbdFilter",            // name of service
                0xF003F);  // full access
            if (hService == IntPtr.Zero)
            {
                MessageBox.Show("OpenService失败,Error Code:" + Marshal.GetLastWin32Error().ToString());
                return false;
            }

            //为了应对程序被移动路径的情况
            //判断注册表中本服务的ImagePath字段是否和当前KCC程序路径相符,不相符则用用当前路径重写
            //如c:\aaa.sys 这样的路径让CreateService在注册表注册服务,实际在注册表中保存的ImagePath是\??\c:\aaa.sys 故和当前路径比对时,当前路径之前要加上\??\
            if (serviceKey.OpenSubKey("SYSTEM").OpenSubKey("CurrentControlSet").OpenSubKey("services").OpenSubKey("kbdFilter").GetValue("ImagePath").ToString() != "\\??\\" + System.AppDomain.CurrentDomain.BaseDirectory + "kbdFilter.sys")
            {
                serviceKey.OpenSubKey("SYSTEM", true).OpenSubKey("CurrentControlSet", true).OpenSubKey("services", true).OpenSubKey("kbdFilter", true).SetValue("ImagePath", "\\??\\" + System.AppDomain.CurrentDomain.BaseDirectory + "kbdFilter.sys", RegistryValueKind.ExpandString);
            }

            //启动服务,到此完成驱动的加载
            if (!StartService(hService, 0, string.Empty))
            {
                MessageBox.Show("StartService失败,Error Code:" + Marshal.GetLastWin32Error().ToString());
                return false;
            }

            //下面开始Ring3和Ring0通信的部分
            for (int i = 0; ; i++)
            {            
                //在驱动中,建立的过滤设备名字是kbdFilter0~kbdFilter1~....~kbdFilter99~kbdFilterX,这样循环增加的形式
                //这里使用"\\\\.\\kbdFilter1""\\\\.\\kbdFilter2"...."\\\\.\\kbdFilter99"去尝试CreateFile取得设备句柄
                //失败说明已经取得了所有过滤设备的句柄,退出循环
                string kbdFilterName = "\\\\.\\kbdFilter" + i.ToString();
                System.IntPtr hDevice = CreateFile(kbdFilterName,
                                        0,  //不需要权限,否则会getlasterror:5
                                        0,
                                        IntPtr.Zero,
                                        3,
                                        4,
                                        IntPtr.Zero
                                        );

                if (hDevice.ToInt32() == -1)
                {
                    break;
                }

                int Len = 0;

                IntPtr Buffer = Marshal.AllocHGlobal(union.Length * Marshal.SizeOf(union[0]));

                Marshal.Copy(union, 0, Buffer, union.Length);
               
                int ret = DeviceIoControl(hDevice,
                      0xa01,
                      Buffer,
                      union.Length * Marshal.SizeOf(union[0]),
                      IntPtr.Zero,
                      0,
                      ref Len,
                      IntPtr.Zero);
                Marshal.FreeHGlobal(Buffer);
                if (ret == 0 && Marshal.GetLastWin32Error().ToString() != "1")
                {
                    // Free the unmanaged memory.
                    MessageBox.Show("DeviceIoControl错误,Error Code:" + Marshal.GetLastWin32Error().ToString());
                    return false;
                }

                //最后句柄是不能忘记关的
                CloseHandle(hDevice);
            }
*******************************************/

/*******************************************
/模块描述:KCC卸载驱动
/作者:葉月
/*******************************************
//下面开始使用Service系列API卸载驱动
            //首先需要OpenSCManager拿到hSCManager
            IntPtr hSCManager = OpenSCManager(null, null, 0xF003F); //SC_MANAGER_ALL_ACCESS (0xF003F)
            if (hSCManager == IntPtr.Zero)
            {
                MessageBox.Show("OpenSCManager失败,Error Code:" + Marshal.GetLastWin32Error().ToString());

                return false;
            }

            //拿到服务句柄
            IntPtr hService = OpenService(
                hSCManager,         // SCM database
                "kbdFilter",            // name of service
                0xF003F);  // full access
            if (hService == IntPtr.Zero)
            {
                MessageBox.Show("OpenService失败,Error Code:" + Marshal.GetLastWin32Error().ToString());

                return false;
            }
            SERVICE_STATUS service_starus = new SERVICE_STATUS();

            //停止设备
            if (!ControlService(hService, 0x00000001, ref service_starus))
            {
                MessageBox.Show("ControlService(停止服务)失败,Error Code:" + Marshal.GetLastWin32Error().ToString());

                return false;
            }

            return true;
*******************************************/

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

上传的附件:
收藏
点赞6
打赏
分享
最新回复 (13)
雪    币: 77
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
葉月 1 2010-3-9 01:31
2
0

=w=用法一目了然了吧~
当然要至少输入一对src和dst键才能按enable的哟~
雪    币: 18
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
xlbr 2010-3-9 09:04
3
0
看不懂,但是帮顶一下
雪    币: 78
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
KenM 2010-3-18 18:09
4
0
我也没整明白!
雪    币: 2174
活跃值: (961)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Crakme 2010-3-18 19:33
5
0

第一次见识了
C#写的程序与ring0的驱动通信
雪    币: 92
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ryanxgyang 2010-3-19 10:04
6
0
雪    币: 293
活跃值: (109)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wtujoxk 2010-3-19 23:14
7
0
正在努力学习中!
雪    币: 248
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
lxmsh 2010-3-20 23:49
8
0
学习!看来自己要恶补一下!!!
雪    币: 2
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
魏子翔 2010-3-21 07:40
9
0
学习了,对于没有编程功底的新手,真是羡慕!
雪    币: 55
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Hedgehogs 2010-3-21 10:29
10
0
很棒,代码拿走读读。感谢楼主。
雪    币: 34
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
lovesnr 2010-3-24 18:58
12
0
dddddddddddddddddddd
雪    币: 34
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
lovesnr 2010-3-24 19:00
13
0
ddddddddddddd
雪    币: 1418
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wwwqazcom 2010-3-25 12:24
14
0
r0 不懂~~
雪    币: 73
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
傾听 2010-3-25 12:32
15
0
来看看
游客
登录 | 注册 方可回帖
返回