kernel Driver Dll 内核模式 DLL编写

原创 2007年10月09日 08:44:00

内核DLL编写

导出驱动程序缺少很多完整内核模式驱动应该有的特征。
(1) 可以为 IRP 处理提供支持例程, 但它不接收 IRP, 所以它不包含派遣例程.
(2) 不存在设备堆栈中
(3) 在服务控制管理器中没有入口点函数(不作为系统服务)
(4) 它确实有 DriverEntry 例程, 但仅仅是为了使代码能编译通过而已, 不被调用
    (注: 程序编译时 bufferoverflowk.lib 中的 GsDriverEntry 例程引用了我们当前项目中的 DirverEntry        例程, 所以如果不定义 DirverEntry, 程序不能通过。 类似于 MSVCRTD.lib 中的 __tmainCRTStartup 引用了 main, 如果我们在C语言中把 main 给去掉了,结果同样是不能编译通过 )


标准驱动程序也可以作为导出驱动程序使用, 不过该驱动程序必须用导出驱动的方法 build, 按照标准驱动程序的方法加载.


构建方法:

(1) 给 TARGETTYPE 赋值为 EXPORT_DRIVER

 TARGETTYPE = EXPORT_DRIVER

(2) 可以使用 DLLDEF 宏指定导出模块定义文件

     DLLDEF="c:/export_drv_test/driver.def"
     导出模块列表为编译器和连接器提供了导出例程信息.

(3) 在导出函数前面加 DECLSPEC_EXPORT

(4) 编译后 生成文件 Export*.lib 和 Export*.sys 文件


导入函数:
在导入函数的前面加上 DECLSPEC_IMPORT.


导出驱动程序必须安装在 %SystemRoot%/system32/drivers 目录中.在 windows NT 4.0中, 导出驱动程序一旦被加载则只有在系统关闭时才被卸载. Windows 2000 以后, 系统保存着一个引用计数, 这个引用计数表示导出驱动程序的函数被其他驱动函数导入的次数。当每个导入了函数的驱动程序被卸载时OS 就减少引用计数。 如果引用计数为0, OS 卸载导出驱动程序.


导出驱动程序必须包含标准的入口点例程 DllInitialize 和卸载例程 DllUnload. 否则引用计数的机制不会起作用. 没有这 2 个例程导出驱动程序一但被加载则只有在系统关闭时才能卸载.


上面的信息参考了 DDK, 参考下面代码和注释,可以发现上面某些信息不太准确.

导出驱动程序例子源码:

/*================================================================================

KernelDLL.cpp

================================================================================*/

/**************************************************************************************************/     
/*                                                                                                */ 
/*                                                                                                */     
/* Notes:                                                                                         */
/*        1) It is not strictly necessary for the executable to be located under the directory    */     
/*           %systemroot%/system32/drivers.  It will work if the executable is located in the     */     
/*           same place as that for the driver that causes the DLL to be loaded.  Neither is the  */     
/*           DLLDEF statement necessary in the soources file.                                     */     
/*                                                                                                */     
/*        2) This kernel DLL will be loaded automagically by the OS when the first driver         */     
/*           importing from this DLL is about to be loaded.  The DLL will be unloaded by the OS   */     
/*           when the last importing driver has been unloaded.                                    */     
/*                                                                                                */     
/*        3) For unloading to be done, both DllInitialize() and DllUnload() must be present and   */     
/*           defined in KernelDLLRtns.def.                                                        */
/*                                                                                                */     
/**************************************************************************************************/     
                                                                                               
#ifdef __cplusplus  // C++ conversion.                                                         
extern "C"                                                                                     
{                                                                                              
#endif              // End #ifdef C++ conversion.                                              
                                                                                               
#include <ntddk.h>
                                                                                               
#ifdef __cplusplus  // C++ conversion.                                                         
}                                                                                              
#endif              // End #ifdef C++ conversion.                                              

//***************************************************************************//
//                                                                           //
// Routine prototypes.                                                       //
//                                                                           //
//***************************************************************************//


/**************************************************************************************************/
/*                                                                                                */
/* DriverEntry                                                                                    */
/*                                                                                                */
/* Notes:                                                                                         */
/*        1) DriverEntry() is required for linking but is never invoked.  DllInitialize() and     */
/*           DllUnload() instead are invoked when the DLL is loaded and unloaded, respectively.   */
/*                                                                                                */
/**************************************************************************************************/
extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT, PUNICODE_STRING)
{
 return STATUS_SUCCESS;
}


/**************************************************************************************************/
/*                                                                                                */
/* Test routine that will be imported and invoked by CallKernelDLL.sys.                           */
/*                                                                                                */
/**************************************************************************************************/
__declspec(dllexport) NTSTATUS KernelDLLRtnsTest( PDEVICE_OBJECT pDevObj )
{
 NTSTATUS                status = STATUS_SUCCESS;

 DbgPrint(("ExportFun is Called!  KernelDLLRtnsTest()/n"));

 return status;
}


/**************************************************************************************************/
/*                                                                                                */
/* Routine that is invoked when the DLL is loaded.                                                */
/*                                                                                                */
/* Notes:                                                                                         */
/*        1) Support for this routine appeared in Win2K.                                          */
/*        2) The presence of DllInitialize() and DllUnload() allows the DLL to be unloaded.       */
/*                                                                                                */
/**************************************************************************************************/
extern "C" NTSTATUS  DllInitialize( PUNICODE_STRING pRegistryPath )
{
 NTSTATUS                status = STATUS_SUCCESS;

 /* COMMONLY INITIALIZE RESOURCES REQUIRED BY OTHER ROUTINES */

 DbgPrint(("DllInitialize() is CALLED /n"));

 return status;
}


/**************************************************************************************************/
/*                                                                                                */
/* Routine that is invoked when the DLL is unloaded.                                              */
/*                                                                                                */
/* Notes:                                                                                         */
/*        1) Support for this routine appeared in Win2K.                                          */
/*        2) The presence of DllInitialize() and DllUnload() allows the DLL to be unloaded.       */
/*                                                                                                */
/**************************************************************************************************/
extern "C" NTSTATUS  DllUnload() 
{
 NTSTATUS                status = STATUS_SUCCESS;

 DbgPrint(("DllUnload() is CALLED/n"));

 return status;
}


/*================================================================================

Sources

================================================================================*/
TARGETNAME=KernelDLL
#TARGETPATH=../lib$(BUILD_ALT_DIR)
TARGETPATH=lib
TARGETTYPE=EXPORT_DRIVER         # SET TYPE OF DRIVER: EXPORT FUNCS
DLLDEF="KernelDLLRtns.def"       # IT IS NOT NECCESOORY TO HAVE THIS STATEMENT. BY DEFAULT, DEL FILE IS  "KernelDLL.def" .

USER_C_FLAGS=$(USER_C_FLAGS) /FAsc

# pick up definitions from external environment

C_DEFINES=$(C_DEFINES)

#
# set up Visual C++ source browsing
#
BROWSER_INFO=1
BROWSERFILE=$(TARGETNAME).bsc -n

INCLUDES=$(BASEDIR)/inc/ddk/wxp

SOURCES=                    /
        KernelDLL.cpp       /

/*================================================================================

KernelDLL.def

================================================================================*/
NAME KernelDLL.sys

EXPORTS

; They act to ensure that these 2 routines are known to the OS, with the result that the kernel DLL can be unloaded.

  DllInitialize private
  DllUnload     private


/*================================================================================

makefile

================================================================================*/
!INCLUDE $(NTMAKEENV)/makefile.def

 

linux驱动模块(多文件)的makefile实现

方式1常用于编写,调试阶段。驱动源码的文件夹位置独立自由,只要在Makefile中指定好Linux内核源码的路径。 方式2常用于最后集成阶段,在调试基本完成后,可以将驱动源代码文件(夹)放置在L...
  • shanzhizi
  • shanzhizi
  • 2013年03月01日 15:46
  • 3620

Uboot中driver驱动和linux内核驱动的区别

说明: 1.和下面论相关的帖子: http://www.crifan.com/records_in_the_uboot_201106_mmc_drive_the_process_of_po...
  • caoyicheng1
  • caoyicheng1
  • 2014年04月10日 17:26
  • 2831

Linux内核编译选项-5

Device Drivers  ---> 驱动程序 Generic Driver Options  --->驱动程序通用选项 (/sbin/hotplug) path to uevent h...
  • pkgfs
  • pkgfs
  • 2013年01月06日 09:53
  • 5557

内核模式DLL

Tim Roberts版权所有 (C) 2003,Tim Roberts。保留所有权利Win32 用户模式程序员已经习惯于使用和创建动态链接库,或者叫 DLL,来划分应用或者达到有效的代码重用。典型的...
  • wuyingfits
  • wuyingfits
  • 2011年07月12日 16:12
  • 2455

内核模式的 DLL

Tim Roberts版权所有 (C) 2003,Tim Roberts。保留所有权利Win32 用户模式程序员已经习惯于使用和创建动态链接库,或者叫 DLL,来划分应用或者达到有效的代码重用。典型的...
  • leibniz_zsu
  • leibniz_zsu
  • 2011年04月09日 22:52
  • 6887

Windows Driver Foundation - KMDF 内核模式驱动框架结构 第五部分

同步问题 因为Windows是抢占的多任务操作系统,多个线程可以并发地访问共享数据结构或资源,而多个驱动例程会并发运行。为了保证数据完整,所有驱动必须同步共享数据结构的访问。正确实现这样的同...
  • cosmoslife
  • cosmoslife
  • 2012年06月18日 06:09
  • 786

Windows Driver Foundation - KMDF 内核模式驱动框架结构 第三部分

KMDF I/O 模型 KMDF建立了自己的派遣例程,其截取了所有发送给驱动的IRP。 图表2说明整个KMDF库和驱动的I/O流程。详细解释见“I/O Request Flow i...
  • cosmoslife
  • cosmoslife
  • 2012年06月18日 06:08
  • 891

Windows Driver Foundation - KMDF 内核模式驱动框架结构 第一部分

简介 内核模式驱动框架(KMDF)是开发内核模式驱动的基础框架。它提供C语言设备驱动接口(DDI),能用来创建Microsoft® Windows® 2000及以后版本的驱动。本质上,框架就是一...
  • cosmoslife
  • cosmoslife
  • 2012年06月18日 06:06
  • 865

中科大网络安全实验获取kernel32.dll内核函数

  • 2016年01月05日 16:19
  • 189KB
  • 下载

使用 C++ 编写内核模式驱动程序的优点与缺点

C++ 及其对象特性似乎与 Microsoft Windows Driver Model (WDM) 和 Windows Driver Foundation (WDF) 驱动程序的语义非常吻合。但是,...
  • pizi0475
  • pizi0475
  • 2011年03月30日 11:15
  • 1934
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:kernel Driver Dll 内核模式 DLL编写
举报原因:
原因补充:

(最多只允许输入30个字)