|
珞珈山水BBS →
电脑网络 →
程序人生 →
单文区文章阅读
|
| 单文区文章阅读 [返回] |
|---|
|
发信人: Stravadivaly (老子就是机器人), 信区: Programm 标 题: 伪驱动初级教程1 发信站: BBS 珞珈山水站 (Fri Sep 1 13:19:37 2006) 伪驱动初级教程1 By Stravadivaly 什么是驱动? 我的感觉,它就是工作在0x8000000以上地址中的“用户程序”。 为什么要写驱动? 因为我们能直接在操作系统的内核中获取信息。而且这些信息很 “干净”, 没有被做过手脚,比如枚举进程。 写驱动要怎样的基础? 最好是写过Windows API 程序。了解消息循环,异常处理。 会使用ring0调试工具,比如softice。 怎么是伪驱动? 就是说我们只是利用驱动程序能工作在核心态的优势,干点我们想 干的事情。简单说,就是占着茅坑不拉屎。 1.安装DDK: DDK(Driver Development Kit, 驱动开发包)是我们写驱动必须安装的咚咚,现在M$已 经开始收费,不再是免费下载了。不过我们还有BT, eMule.(他们不仅仅可以用来下毛片) 。 下载好了之后,开始安装,随便装到哪个目录。在开始菜单中我们就可以看到一个“ Development Kit”的目录,在其后面的 “Build Enviroments”项下面我们可以看到有许 多的DOS快捷方式,这些就是编译环境。他们之间的区别和VC中的checked , release的区 别是相同的。Cheched版本中保留了很多调试信息,因而体积比release肥。我们调试的时 候,就是用Checked 环境编译的程序。 安装目录下面有DDK文档,就像MSDN。也有示例驱动。 2.编写环境: 很抱歉,M$似乎还没有一个专门的驱动编写环境。DriverStdio有,也听说网上由帖子 教你把VC配置成驱动编写编译工具的文章, 我两个都不用, 只拿个记事本,或者就用VC 写。注意,只是用他们写。更听说过有类似MFC的,对DDK的封装后的编译环境,我没有尝 试,我喜欢干净点的,直接点的。 3.编译一个驱动需要的文件: .c 文件:就是我们编写的驱动源程序。不能是 .cpp 文件,不然会编译错误。 Makefile:如同编译汇编语言的MakeFile,这里也需要一个Makefile文件,但所有的驱 动的这个文件都是一样的,你可以到DDK的安装目录下面随便考一个。 Sources: 最简单的sources文件像下面这样: TARGETNAME=MYDRIVER0 //这个是可以更改的,怎么改以后再说 TARGETTYPE=DRIVER TARGETPATH=obj SOURCES=MyDriver.c //这个是我们编写的驱动源程序,也可以改。 这三个文件放到一起,然后我们打开编译环境,也就是开始菜单中,DDK项下面的Che cked Enviroments。可以看到提示符了吧?用一系列DOS命令转到我们准备的三个文件所在 目录。输入命令 Build Mydriver.c –cZ 。之后也许是错误连天, 也许我们会发现当前 目录下多了两个文件夹,其中一个叫objchk,它下面还有一个文件夹 i386, i386的下面你 可以找到你编译好的.sys文件。 3.安装驱动: 我们写了驱动是要安装的,不然有什么用? 有两种加载方式:1.通过.inf文件直接 写注册表。 2.写用户态程序,加载。推荐用程序加载, 下面是个完整的程序,来自国外 的某个牛人: //安装驱动程序代码 /*++ Copyright (c) 1993 Microsoft Corporation Module Name: Instdrv.c Abstract: A simple Win32 app that installs a device driver Environment: user mode only Notes: See readme.txt Revision History: 06-25-93 : created //人家93年就写了…... --*/ #include <windows.h> #include <stdio.h> #include <stdlib.h> #include <string.h> BOOL InstallDriver( IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName, IN LPCTSTR ServiceExe ); BOOL RemoveDriver( IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName ); BOOL StartDriver( IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName ); BOOL StopDriver( IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName ); BOOL OpenDevice( IN LPCTSTR DriverName ); VOID __cdecl main(IN int argc,IN char *argv[]) /*++ Routine Description: Arguments: Return Value: --*/ { SC_HANDLE schSCManager; if (argc != 3){ char currentDirectory[128]; printf ("usage: instdrv <driver name> <.sys location>\n"); printf (" to install a kernel-mode device driver, or:\n"); printf (" instdrv <driver name> remove\n"); printf (" to remove a kernel-mode device driver\n\n"); GetCurrentDirectory (128,currentDirectory); printf(" Example: instdrv simpldrv %s\simpldrv.sys\n",currentDirectory ); exit (1); } schSCManager = OpenSCManager (NULL, // machine (NULL == local) NULL, // database (NULL == default) SC_MANAGER_ALL_ACCESS // access required ); if (!_stricmp (argv[2],"remove")){ StopDriver (schSCManager,argv[1]); RemoveDriver (schSCManager,argv[1]); } else{ InstallDriver(schSCManager,argv[1],argv[2]); StartDriver (schSCManager,argv[1]); OpenDevice (argv[1]); } CloseServiceHandle (schSCManager); } BOOL InstallDriver( IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName, IN LPCTSTR ServiceExe ) /*++ Routine Description: Arguments: Return Value: --*/ { SC_HANDLE schService; DWORD err; // // NOTE: This creates an entry for a standalone driver. If this // is modified for use with a driver that requires a Tag, // Group, and/or Dependencies, it may be necessary to // query the registry for existing driver information // (in order to determine a unique Tag, etc.). // schService = CreateService (SchSCManager, // SCManager database DriverName, // name of service DriverName, // name to display SERVICE_ALL_ACCESS, // desired access SERVICE_KERNEL_DRIVER, // service type SERVICE_DEMAND_START, // start type SERVICE_ERROR_NORMAL, // error control type ServiceExe, // service's binary NULL, // no load ordering group NULL, // no tag identifier NULL, // no dependencies NULL, // LocalSystem account NULL // no password ); if (schService == NULL){ err = GetLastError(); if (err == ERROR_SERVICE_EXISTS){ // // A common cause of failure (easier to read than an error code) // printf ("failure: CreateService, ERROR_SERVICE_EXISTS\n"); } else{ printf ("failure: CreateService (%d)\n",err); } return FALSE; } else{ printf ("CreateService SUCCESS\n"); } CloseServiceHandle (schService); return TRUE; } BOOL RemoveDriver( IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName ) /*++ Routine Description: Arguments: Return Value: --*/ { SC_HANDLE schService; BOOL ret; schService = OpenService (SchSCManager, DriverName, SERVICE_ALL_ACCESS); if (schService == NULL){ printf ("failure: OpenService (%d)\n", GetLastError()); return FALSE; } ret = DeleteService (schService); if (ret){ printf ("DeleteService SUCCESS\n"); } else{ printf ("failure: DeleteService (%d)\n",GetLastError()); } CloseServiceHandle (schService); return ret; } BOOL StartDriver( IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName ) { SC_HANDLE schService; BOOL ret; DWORD err; schService = OpenService (SchSCManager, DriverName, SERVICE_ALL_ACCESS); if (schService == NULL){ printf ("failure: OpenService (%d)\n", GetLastError()); return FALSE; } ret = StartService (schService, // service identifier 0, // number of arguments NULL // pointer to arguments ); if (ret){ printf ("StartService SUCCESS\n"); } else{ err = GetLastError(); if (err == ERROR_SERVICE_ALREADY_RUNNING){ // // A common cause of failure (easier to read than an error code) // printf ("failure: StartService, ERROR_SERVICE_ALREADY_RUNNING\n"); } else{ printf ("failure: StartService (%d)\n",err); } } CloseServiceHandle (schService); return ret; } BOOL StopDriver( IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName ) { SC_HANDLE schService; BOOL ret; SERVICE_STATUS serviceStatus; schService = OpenService (SchSCManager, DriverName, SERVICE_ALL_ACCESS ); if (schService == NULL){ printf ("failure: OpenService (%d)\n", GetLastError()); return FALSE; } ret = ControlService (schService, SERVICE_CONTROL_STOP, &serviceStatus ); if (ret){ printf ("ControlService SUCCESS\n"); } else{ printf ("failure: ControlService (%d)\n",GetLastError()); } CloseServiceHandle (schService); return ret; } BOOL OpenDevice( IN LPCTSTR DriverName ) { char completeDeviceName[64] = ""; LPCTSTR dosDeviceName = DriverName; HANDLE hDevice; BOOL ret; // // Create a \.\XXX device name that CreateFile can use // // NOTE: We're making an assumption here that the driver // has created a symbolic link using it's own name // (i.e. if the driver has the name "XXX" we assume // that it used IoCreateSymbolicLink to create a // symbolic link "\DosDevices\XXX". Usually, there // is this understanding between related apps/drivers. // // An application might also peruse the DEVICEMAP // section of the registry, or use the QueryDosDevice // API to enumerate the existing symbolic links in the // system. // strcat (completeDeviceName,"\\.\"); strcat (completeDeviceName,dosDeviceName); hDevice = CreateFile (completeDeviceName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if (hDevice == ((HANDLE)-1)){ printf ("Can't get a handle to %s\n",completeDeviceName); ret = FALSE; } else{ printf ("CreateFile SUCCESS\n"); CloseHandle (hDevice); ret = TRUE; } return ret; } -- 是吗? 不是吗? 对吗? 不对吗? 傻吗? ...... 的确很傻. 就像" 树动风欲静, 日涌大山流". ※ 来源:·珞珈山水BBS站 http://bbs.whu.edu.cn·[FROM: 218.247.215.*] |
| [返回单文区目录] |
|
|