原文链接:使用GCC创建 Windows NT 下的内核DLL

在温习<<Windows 2000 Driving>>分层驱动程序一章的时候,看到了关于紧耦合驱动连接方式,这种方式不依赖于I/O管理器的串联,而是直接调用内核例程,这样可以大大的提高驱动的执行效率。

为了实现这样一种功能,必须提供一种类似于在用户模式中DLL的机制,只不过该"DLL"是加载到内核中的。其实Windows NT 内核本身早就利用了这样机制,比如Hal.dll、ntoskrnl.exe和某些类驱动程序等,他们分别为第3方驱动程序导出了HAL层、内核层、执行体层的功能函数。

在 Tim Roberts 的 《内核模式的 DLL》一文中,给出了内核DLL的主要特征:

    内核 DLL 就像用户模式 DLL 一样:链接器在构建 DLL 时生成一个导入库,然后将此库包含到将要使用此DLL 的任何驱动程序的目标库列表中。既不需要注册表技巧,也不需要任何特别的动作来起停该 DLL。内核 DLL将随任何引用之的其他驱动程序自动加载,而随最后一个引用之的驱动程序自动卸载(注 1)。

为了实现这样一个DLL,Roberts给出的做法是使用DDK来生成一个TARGETTYPE为EXPORT_DRIVER的项目。我试了一下,如其所愿,的确建立一个xxx.sys文件,我还观察了一下该sys的PE类型,发现它与标准的内核sys并无两样,那么能不能用gcc来生成一个内核模式的DLL呢?答案是肯定的!如果你正在用gcc(MinGW)在写Windows NT 下的Core Dll的话,那么也可以写出DDK中EXPORT_DRIVER类型的模块了,具体做法从略...

好了,上面只是开个玩笑,呵呵。下面就详细说说如何用MinGW来写一个CoreDll:

  1. 首先在你的系统中应该安装一个MinGW,我现在用的是(MinGW 5.1.4);
  2. 在你的系统中还要有一个Masm32V9.0+的环境(这个不是必须的,Gcc也有能力自己生成驱动程序文件,而我采用的是Masm方式),你也可以安装WINDDK,用它的环境生成最终的的驱动文件。
  3. 用gccNTDrvFrame(注2)建立一个新的驱动包,其中如果要想实现CoreDll动态加载和卸载功能必须在sys.c中提供以下2个例程,你可以将构造和析构的相关内容放在它们里面。你同样要提供一个Driver 必须包含标准的 DriverEntry 入口点,不过实际上系统不会调用它。这个需求是创建系统的人为限制,因为它会为每个内核驱动程序把 /ENTRY:DriverEntry 添加到链接器选项中。因此我们为只导出的 DLL 也必须提供一个伪入口点。
 __declspec(dllexport) DDKAPI NTSTATUS DllInitialize(/
IN PUNICODE_STRING RegistryPath);
__declspec(dllexport) DDKAPI NTSTATUS DllUnload(void);

4.  建立一个需要导出的函数,我这里只是示例一下,所以写了一个简单的导出函数:

 __declspec(dllexport) DDKAPI NTSTATUS GetMagicNum(IN int *pVal)
{
if(!pVal)
{
DbgPrint("err : pVal == NULL!/n");
return STATUS_DEVICE_CONFIGURATION_ERROR;
}
DbgPrint("*pVal is %d/n",*pVal);
*pVal *= * ;
DbgPrint("After OP --- *pVal is %d/n",*pVal);
return STATUS_SUCCESS

5. 为连接器建立def文件,内容如下:

NAME CoreDll.sys
EXPORTS
DllInitialize PRIVATE
DllUnload PRIVATE
GetMagicNum

6. 运行gccNTDrvFrame的builder,完成CoreDll的编译和连接,如果没有错误将会生成若干个文件,其中只会用到2个:一个是xxx.sys,这个不用说就是供其它驱动调用的CoreDll,另一个是xxx.lib,它是所有需要调用xxx.sys的其它驱动程序建立时需要的文件,它和hal.lib、ntoskrnl.lib完全一样。

7. 新建另一个Driver工程,在b.bat中的link连接选项中添加xxx.lib。声明和调用外部函数的方法如下:

__declspec(dllimport) DDKAPI NTSTATUS GetMagicNum(IN int *pVal);
DDKAPI NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,/
PUNICODE_STRING pRegistryPath)
{
PDEVICE_OBJECT pDevObj;
NTSTATUS status = STATUS_DEVICE_CONFIGURATION_ERROR; PRINT("[%s]enter DriverEntry.../n",__func__); RtlInitUnicodeString(&DevName,DEVNAMEW);
RtlInitUnicodeString(&SymlnkName,SYMLNKNAMEW); if(IoCreateDevice(pDriverObject,,&DevName,FILE_DEVICE_UNKNOWN,/
,false,&pDevObj) != STATUS_SUCCESS)
{
PRINT("[%s]IoCreateDevice Failed!/n",__func__);
goto QUIT;
} if(IoCreateSymbolicLink(&SymlnkName,&DevName) != STATUS_SUCCESS)
{
IoDeleteDevice(pDevObj);
PRINT("[%s]IoCreateSymbolicLink Failed!/n",/
__func__);
goto QUIT;
} pDevObj->Flags |= DO_BUFFERED_IO; pDriverObject->DriverUnload = DriverUnload;
pDriverObject->MajorFunction[IRP_MJ_CREATE] = /
DrvDispatchCreateClose;
pDriverObject->MajorFunction[IRP_MJ_CLOSE] = /
DrvDispatchCreateClose;
pDriverObject->MajorFunction[IRP_MJ_READ] = /
DispatchRead;
pDriverObject->MajorFunction[IRP_MJ_WRITE] = /
DispatchWrite;
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = /
DrvDispatchControl;
pDriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = /
DrvShutdown;
if(!NT_SUCCESS(IoRegisterShutdownNotification(/
pDriverObject->DeviceObject)))
{
PRINT("[%s]err : Register Shutdown Failed!/n",/
__func__);
} int i = ;
GetMagicNum(&i); PRINT("[%s]Addr of KeServiceDescriptorTable : %p/n",/
__func__,KeServiceDescriptorTable);
PRINT("[%s]leave DriverEntry.../n",__func__); status = STATUS_SUCCESS;
QUIT:
return status;
}

你当然不一定非要在DriverEntry中调用,因为xxx.sys由系统在调用sys之前自动动态加载.

8. 用builder建立这个sys,然后整个过程结束了。

结束语:这里只是一个最简单的示例,如果是只干这样的"小"事而用CoreDll的话,未免杀鸡用牛刀的意思。CoreDll的用途可以被极大的拓展,至于如何发挥您的激情与才干,就不是我力所能及的了。(^o^)

注1 :不过,在 Windows 98 第二版或者 Windows Me 中内核 DLL 永远也不会卸载。

注2 gccNTDrvFrame是我写的一个gcc建立windows NT 驱动的框架包,稍后会在新文章中介绍。

(PS : 文章参考http://sluttery.spaces.live.com/blog/cns!3569FEA80C717FD4!519.entry

[原创]使用GCC创建 Windows NT 下的内核DLL的更多相关文章

  1. [原创]python MySQLdb在windows环境下的安装、出错问题以及解决办法

    版权声明:本文为博主原创文章,未经博主允许不得转载. 问题:windows下安装MySQLdb的方法 解析:python没有php那种集成环境,比如wamp那种集成软件直接把所有需要的东西全部一次性搭 ...

  2. 创建windows系统下的虚拟机

    创建新的虚拟机  添加映像(windows系统下必须先添加映像) 选择相应的镜像文件:网上查找密钥输入:版本按要求选择:单击 下一步:设置虚拟机名称  位置 :下一步 默认的磁盘大小(不用管)——下一 ...

  3. windows环境下lib和dll的区别和联系详细

    https://blog.csdn.net/ghevinn/article/details/43759655 c++中共有两种库:1.LIB包含了函数所在的DLL文件和文件中函数位置的信息(入口),代 ...

  4. 【WIN7】windows\system32 下的几乎所有文件的简单说明【2】

    1: System32的详解 C:\WINDOWS\system32... 2:   3: 这个 system32 文件夹中包含了大量的用于 Windows 的文件. 这里主要用于存储 DLL 文件, ...

  5. 【WIN7】windows\system32 下的几乎所有文件的简单说明【1】

    1: aclui.dll .....Security Descriptor Editor,没有它,注册表编缉器会无法运行 2: ACTIVEDS.DLL .....(ADs 路由层 DLL). 没有它 ...

  6. [原创]浅谈NT下Ring3无驱进入Ring0的方法

    原文链接:浅谈NT下Ring3无驱进入Ring0的方法 (测试环境:Windows 2000 SP4,Windows XP SP2.Windows 2003 未测试) 在NT下无驱进入Ring0是一个 ...

  7. Windows平台下解决Oracle12c使用PDB数据库创建SDE的问题 分类: oracle sde 2015-06-12 11:03 88人阅读 评论(0) 收藏

    Windows平台下解决Oracle12c使用PDB数据库创建SDE的问题 Oracle 12C中引入了CDB与PDB的新特性,在ORACLE 12C数据库引入的多租用户环境(Multitenant ...

  8. windows环境下创建 .文件夹

    一.windows环境下创建 .文件夹 1.新建一个文件夹 2.重命名为.properties.(名字前后都加点) 二.windows环境下创建 .文件 1.上面的方法对文件同样适用 2.运行CMD, ...

  9. Android开发之 Windows环境下通过Eclipse创建的第一个安卓应用程序(图文详细步骤)

    第一篇  windows环境下搭建创建的第一个安卓应用程序 为了方便,我这里只采用了一体包进行演示. 一.下载安卓环境的一体包. 官网下载:安卓官网(一般被墙了) 网盘下载: http://yunpa ...

随机推荐

  1. Vijos 1121 马拦过河卒

    首先要看清题目,卒只能向右或者向下走.而不是四周转.这样的话就无解了. 定义f[i][j],表示走到(i,j)这个点时的总步数.这样就写出了一个递推公式f[i][j]=f[i-1]+f[i][j-1] ...

  2. BZOJ 2780: [Spoj]8093 Sevenk Love Oimaster( 后缀数组 + 二分 + RMQ + 树状数组 )

    全部串起来做SA, 在按字典序排序的后缀中, 包含每个询问串必定是1段连续的区间, 对每个询问串s二分+RMQ求出包含s的区间. 然后就是求区间的不同的数的个数(经典问题), sort queries ...

  3. Qt使用快捷键

    在说快捷键之前先来说一个QtCreator调试的过程中经常发生的一个问题. 问题描述: 用QtCreator建立了一个纯C++的项目,但是在F5调试时,竟然提示ptrace不允许的操作,修改工程配置为 ...

  4. 关于sql 外键的讨论。

    外键是否采用看业务应用场景,以及开发成本的,大致列下什么时候适合,什么时候不适合使用: 1. 互联网行业应用不推荐使用外键: 用户量大,并发度高,为此数据库服务器很容易成为性能瓶颈,尤其受IO能力限制 ...

  5. eclipse 和myEclipse 项目导入

    经常在eclipse/myeclipse中导入web项目时,出现转不了项目类型的问题,导入后就是一个java项目. 有两种情况: 一.eclipse无法识别其他eclipse的web项目 解决步骤: ...

  6. 开博第二篇:记一个利用JavaScript,编写PS脚本,开发图片量产工具

    背景:身在一个有实业的电商公司,设计部的妹子们总是会有做不完的商品图片,当然了,要是做点有技术含量的美化工作也罢,但是最近她们很是无聊,总是要做一些重复性的工作,就比如如题所说的,图片量产,量产什么呢 ...

  7. 设置php在apache下加载ini配置文件路径,~和curl扩展无法加载的问题

    php以模块的方式加载到apache的时候,php配置文件目录为C:windows.这不合理,应该选择php本身目录的配置文件加载,可以在apache的httpd.conf配置文件里设置PHPIniD ...

  8. 【翻译】MVC Music Store 教程-概述(一)

    MVC Music Store教程介绍和说明了如何一步步的用ASP.NET MVC 和Visual Web Developer 进行Web开发,教程从最基础的阶段开始,所以对于初级阶段的开发者来说,也 ...

  9. 正则语言(转的 大额_skylar )

    备注:正则表达式真的很头疼,收集起来,用起来很方便的. 常用的元字符 . 匹配除换行符以外的任意字符 \w 匹配字母或数字或下划线或汉字 \s 匹配任意的空白符 \d 匹配数字 \b 匹配单词的开始或 ...

  10. 论山寨手机与Android联姻 【4】手机产业链

    前文说到,生产手机以前,制造厂家需要预先得到软硬件的产品级设计方案,然后按照设计方案亦步亦趋地做,就可以制造出手机了.软硬件的产品级设计包括以下内容, 1. 主板设计,或者Gerber文件,或者PCB ...