首页
社区
课程
招聘
[原创]使用GCC创建 Windows NT 下的内核DLL
发表于: 2009-6-30 11:48 7607

[原创]使用GCC创建 Windows NT 下的内核DLL

2009-6-30 11:48
7607

【原创】使用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:

 
__declspec(dllexport) DDKAPI NTSTATUS DllInitialize(\   
IN PUNICODE_STRING RegistryPath);   
__declspec(dllexport) DDKAPI NTSTATUS DllUnload(void);  
__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 *= 11 * 11;   
DbgPrint("After OP --- *pVal is %d\n",*pVal);   
return STATUS_SUCCESS  
[LIST=1]
[*]NAME CoreDll.sys   
[*]EXPORTS   
[*] DllInitialize PRIVATE   
[*] DllUnload PRIVATE   
[*] GetMagicNum  
[/LIST]
[LEFT]__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;   [/LEFT]
 
[LEFT]  PRINT("[%s]enter DriverEntry...\n",__func__);   [/LEFT]
 
[LEFT]  RtlInitUnicodeString(&DevName,DEVNAMEW);   
  RtlInitUnicodeString(&SymlnkName,SYMLNKNAMEW);   [/LEFT]
 
[LEFT]  if(IoCreateDevice(pDriverObject,0,&DevName,FILE_DEVICE_UNKNOWN,\   
      0,false,&pDevObj) != STATUS_SUCCESS)   
  {   
      PRINT("[%s]IoCreateDevice Failed!\n",__func__);   
      goto QUIT;   
  }   [/LEFT]
 
[LEFT]  if(IoCreateSymbolicLink(&SymlnkName,&DevName) != STATUS_SUCCESS)   
  {   
      IoDeleteDevice(pDevObj);   
      PRINT("[%s]IoCreateSymbolicLink Failed!\n",\   
          __func__);   
      goto QUIT;   
  }   [/LEFT]
 
[LEFT]  pDevObj->Flags |= DO_BUFFERED_IO;   [/LEFT]
 
[LEFT]  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__);   
  }   [/LEFT]
 
[LEFT]  int i = 11;   
  GetMagicNum(&i);   [/LEFT]
 
[LEFT]  PRINT("[%s]Addr of KeServiceDescriptorTable : %p\n",\   
      __func__,KeServiceDescriptorTable);   
  PRINT("[%s]leave DriverEntry...\n",__func__);   [/LEFT]
 
[LEFT]  status = STATUS_SUCCESS;   
QUIT:   
  return status;   
}[/LEFT]

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 7
支持
分享
最新回复 (3)
雪    币: 208
活跃值: (40)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
坐沙发,等下文
2009-6-30 11:53
0
雪    币: 442
活跃值: (107)
能力值: ( LV9,RANK:350 )
在线值:
发帖
回帖
粉丝
3
不会吧,精华延时这么长时间???
2009-12-3 17:42
0
雪    币: 38
活跃值: (536)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
4
不错,学习了!!
2009-12-3 19:37
0
游客
登录 | 注册 方可回帖
返回
//