首页 网络安全 安全学院 查看内容

菜鸟也写驱动程序

2009-6-27 11:28 731 0

摘要:   1.编译器  驱动说到底是由编译器产生的一个二进制文件,后缀sys,和普通的"console application "和"WINDOWS application "一样,也是pe结构,但是他们运...
关键词: 驱动 SERVICE pDriverObj hService usDosDeviceName 函数 NULL hSCManager Example 程序

  1.编译器  驱动说到底是由编译器产生的一个二进制文件,后缀sys,和普通的"console application "和"WINDOWS application "一样,也是pe结构,但是他们运行的子系统不同,link时driver程序链接的子系统为NATIVE,为编译器传递/SUBSYSTEM:NATIVE参数.一般不用手动命令行的方式打命令编译,可以写好makefile(内容固定不变)和SOURCE文件,cd 到程序目录下,build即可,还可以用前辈制作的vc向导生成,或者用更简单的quicksys,easysys等工具编译.搜索一下全都有了-_- quicksys我只能用0.2版本的,最新的0.4版本用着有些问题..  2.入口点,驱动的"main"函数  我们知道一个简单的console程序入口点通常为main,windows程序入口点为WinMain,驱动也有类似的东西,被称为DriverEntry例程,是每个驱动函数必须要有的,原型如下:  NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath);  这个例程由I/O管理器在装载时调用.并在注册表里生成相关键值,也就是传递的第二个参数,UNICODE_STRING字符串指针,指向该键值.驱动里统一用UNICODE_STRING,它不是普通的数据,而是一个结构体,而且不是NULL结尾的,如果NULL结尾,将产生蓝屏.初始化要用特殊手段,调用RtlInitUnicodeString函数.  DRIVER_OBJECT是一个用来代表(represent)驱动的数据结构,用他来初始化驱动一些数据结构,为他们例程做准备工作.指向返回NTSTATUS系统状态.  3.DriverUnload例程  参数为一个DriverOjbect,如其名,由DriverOjbect的unload域指定,做一些清理工作,比如删除设备对象,删除符号连接等工作,名称可以任意.  创建了链接名,设备才能为win32子系统可见,  3.DeviceOjbect, 设备对象  设备对象是代表I/O操作目标的虚拟/逻辑/物理设备,我的理解是驱动程序负责创建出来真正起实际作用的,是Driver程序操作的目标对象.由IoCreateDevice创建,IoCreateDevice在DriverEntry或AddDevice中调用,取决于是否为WDM模型,我们编写的一般都不是WDM模型,所以在DriverEntry中调用,下面是一段代码:  代码:  NTSTATUS  DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString)  {  NTSTATUS status;  ULONG ulDeviceNumber = 0;  pDriverObj->DriverUnload = ExampleUnload;  PDEVICE_OBJECT pDevObj;  UNICODE_STRING usDeviceName,usDosDeviceName;  RtlInitUnicodeString(&usDeviceName,L"\\Device\\Example");  RtlInitUnicodeString(&usDosDeviceName,L"\\Dos\\DosDevices\\Example");  status = IoCreateDevice(pDriverObj,0,  &usDeviceName,FILE_DEVICE_UNKNOWN,  FILE_DEVICE_SECURE_OPEN,  FALSE,&pDevObj);  IoCreateSymbolicLink(&usDosDeviceName,&usDeviceName);  return status;  }  void ExampleUnload(PDRIVER_OBJECT pDriverObj)  {  // delete symboliclink  UNICODE_STRING usDosDeviceName;  RtlInitUnicodeString(&usDosDeviceName,L"\\Dos\\DosDevices\\Example");  IoDeleteSymbolicLink(&usDosDeviceName);  // delete the Device  IoDeleteDevice(pDriverObj->DeviceObject);  }  4.驱动loader  这已经是一个驱动了,可以调用各类核心函数,前提是要把它加载到内存中去,程序如下:  代码:  int _cdecl main(void)  {  HANDLE hSCManager;  HANDLE hService;  SERVICE_STATUS ss;  hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);  printf("Load Driver\n");  if(hSCManager)  {  printf("Create Service\n");  hService = CreateService(hSCManager, "Example",  "Example Driver",  SERVICE_START | DELETE | SERVICE_STOP,  SERVICE_KERNEL_DRIVER,  SERVICE_DEMAND_START,  SERVICE_ERROR_IGNORE,  "C:\\example.sys",  NULL, NULL, NULL, NULL, NULL);  if(!hService)  {  hService = OpenService(hSCManager, "Example",  SERVICE_START | DELETE | SERVICE_STOP);  }  if(hService)  {  printf("Start Service\n");  StartService(hService, 0, NULL);  printf("Press Enter to close service\r\n");  getchar();  ControlService(hService, SERVICE_CONTROL_STOP, &ss);  DeleteService(hService);  CloseServiceHandle(hService);  }  CloseServiceHandle(hSCManager);  }  return 0;  }  初学也可以用一些驱动加载用具,自动加载,启动,停止,卸载,比如说coderui所写的图形化工具  http://hi.baidu.com/coderui  里面还可以打印出一些调试信息,加入DbgPrint(),用Sysinternals DebugView,http://www.sysinternals.com/  5.Dispatch例程  但他还不能响应I/O请求,比如说read,write等,要为他们编写Dispatch例程  Dispatch例程的作用就是充当I/O请求与驱动之间的桥梁,用来标识不同I/O操作类型的是IRP_MJ_XXX主功能码  Dispatch例程函数指针存放在驱动对象MajorFunction数组中,主功能码用于索引该数组,填入以激活各例程.  pDriverObj->MajorFunction[IRP_MJ_CREATE]=DispatchCreate;  pDriverObj->MajorFunction[IRP_MJ_CLOSE]=DispatchClose;  pDriverObj->MajorFunction[IRP_MJ_READ] =DispatchRead;  pDriverObj->MajorFunction[IRP_MJ_WRITE] =DispatchWrite;  windows中应用程序通过调用win32函数与驱动进行通信.用CreateFile打开设备获得句柄,ReadFile从驱动中读取数据,WriteFile写入数据,程序退出时,CloseHandle关闭设备等,一一对应关系图:  CreateFile  IRP_MJ_CREATE  CloseHandle  IRP_MJ_CLEANUP  CloseHandle  IRP_MJ_CLOSE  ReadFile    IRP_MJ_READ  WriteFile  IRP_MJ_WRITE  ...  WriteFile分几种情况,有缓冲的和无缓冲的,比较复杂,不深入了因为我还没完全掌握,编写这些函数参看火影的这篇文章,他的那篇是wdm模型,  http://bbs.pediy.com/showthread.php?t=58251  最后再推荐本书  The Windows 2000 Device Driver Book(Second Edition)其他书比较难看懂..  本文是半翻译了codeproject上Introduction to Drivers part1和其他驱动书写的菜鸟之作.
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

最新评论

返回顶部