其实也不是想学驱动,主要是要在ring 0 下的程序,都是通过驱动实现的.找了几本驱动的电子书,给自己看晕了,http://www.driverdevelop.com/forum/ 这里很好,很多高手
windows的驱动好几种,9x下的Vxd,和nt下的KMD,和现在的WDM,kmd说是nt4的时候用的,,用汇编,,我在网上找了份英文的TutoriAl,需要用kmd develop kits,,不过文章里用MASM7 编译的,,不懂到底都什么关系,
现在都还没弄明白wdm到底是什么,怎么会有的driver是wdm,有的就不是
网上有一个改windows的idt的,把程序都贴出来
//********************************************************
// AddMyInt
//
// write by sinister
//
//********************************************************
#include "ntddk.h"
#pragma pack(1)
//定义 IDTR
typedef struct tagIDTR {
//段界限
short Limit;
//段基址
unsigned int Base;
}IDTR, *PIDTR;
//定义 IDT
typedef struct tagIDTENTRY {
unsigned short OffsetLow;
unsigned short Selector;
unsigned char Reserved;
unsigned char Type:4;
unsigned char Always0:1;
unsigned char Dpl:2;
unsigned char Present:1;
unsigned short OffsetHigh;
} IDTENTRY, *PIDTENTRY;
#pragma pack()
// 添加的中断
#define MYINT 0x76
extern VOID _cdecl MyIntFunc();
CHAR IDTBuffer[6];
IDTENTRY OldIdt;
PIDTR idtr = (PIDTR)IDTBuffer;
static NTSTATUS MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
VOID DriverUnload (IN PDRIVER_OBJECT pDriverObject);
// 我们的中断处理函数
VOID _cdecl MyIntFunc()
{
DbgPrint("WSS- Call MyInt is ok/n");
_asm iretd; //中断返回
}
NTSTATUS AddMyInt()
{
PIDTENTRY Idt;
//得到 IDTR
_asm{
sidt IDTBuffer
}
Idt = (PIDTENTRY)idtr->Base; //得到IDT基地址
//保存原有的 IDT
RtlCopyMemory(&OldIdt, &Idt[MYINT], sizeof(OldIdt));
//禁止中断
_asm cli
//设置 IDT 各项添加我们的中断
Idt[MYINT].OffsetLow = (unsigned short)MyIntFunc; //取中断处理函数低16位
Idt[MYINT].Selector = 8; //设置内核段选择子
Idt[MYINT].Reserved = 0; //系统保留
Idt[MYINT].Type = 0xE; //设置0xE表示是中断门
Idt[MYINT].Always0 = 0; //系统保留必须为0
Idt[MYINT].Dpl = 3; //描述符权限,设置为允许 RING 3 进程调用
Idt[MYINT].Present = 1; //存在位设置为1表示有效
Idt[MYINT].OffsetHigh = (unsigned short)((unsigned int)MyIntFunc>>16); //取中断处理函数高16位
//开中断
_asm sti
return STATUS_SUCCESS;
}
//删除中断
VOID RemoveMyInt()
{
PIDTENTRY Idt;
Idt = (PIDTENTRY)idtr->Base;
_asm cli
//恢复 IDT
RtlCopyMemory(&Idt[MYINT], &OldIdt, sizeof(OldIdt));
_asm sti
}
// 驱动入口
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath )
{
UNICODE_STRING nameString, linkString;
PDEVICE_OBJECT deviceObject;
NTSTATUS status;
WCHAR wBuffer[200];
nameString.Buffer = wBuffer;
nameString.MaximumLength = 200;
//卸载驱动
DriverObject->DriverUnload = DriverUnload;
//建立设备
RtlInitUnicodeString( &nameString, L"//Device//WSSINT" );
status = IoCreateDevice( DriverObject,
0,
&nameString,
FILE_DEVICE_UNKNOWN,
0,
TRUE,
&deviceObject
);
if (!NT_SUCCESS( status ))
return status;
RtlInitUnicodeString( &linkString, L"//??//WSSINT" );
//使WIN32应用程序可见
status = IoCreateSymbolicLink (&linkString, &nameString);
if (!NT_SUCCESS( status ))
{
IoDeleteDevice (DriverObject->DeviceObject);
return status;
}
//添加中断
AddMyInt();
DriverObject->MajorFunction[IRP_MJ_CREATE] = MydrvDispatch;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = MydrvDispatch;
return STATUS_SUCCESS;
}
static NTSTATUS MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
NTSTATUS status;
UNREFERENCED_PARAMETER( DeviceObject );
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0L;
status = STATUS_SUCCESS;
IoCompleteRequest( Irp, 0 );
return status;
}
VOID DriverUnload (IN PDRIVER_OBJECT pDriverObject)
{
UNICODE_STRING nameString;
RemoveMyInt();
RtlInitUnicodeString( &nameString, L"//??//WSSINT" );
//删除WIN32可见
IoDeleteSymbolicLink(&nameString);
//删除设备
IoDeleteDevice(pDriverObject->DeviceObject);
return;
}
client:
TestAddInt.c
int main(int argc, char* argv[])
{
_asm {
int 76h
}
return 0;
}
就是一个通过驱动来在ring 0运行程序的框架吧,,,
编译要用ddk,安装ddk 和vc,,我安的是win2k的ddk,,这东西和symbols不一样,,2000的ddk照样在xp下用,,我是xp sp2
自己一点都不会,刚看了没多久,,,编译选项还没看,,
把程序放到一个目录下,,参照着其他的驱动程序里的SOURCES文件,,自己也弄一个过来,,内容:
TARGETNAME=uu
TARGETPATH=obj
TARGETTYPE=DRIVER
MSC_WARNING_LEVEL=/W3
SOURCES=mydriver1.c
SOURCES=就把需要的文件全列着,用/分隔
还需要一个mAkefile文件,,很郁闷,,似乎每个驱动程序里的mAkefile文件都一样,都那么一句话,,可没有就是编译不了,,
#
# DO NOT EDIT THIS FILE!!! Edit ./sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the components of NT OS/2
#
!INCLUDE $(NTMAKEENV)/makefile.def
就这些内容,,在这个驱动里,把这三个文件放到一个目录里以后,找ddk的环境设置的那个文件,在开始里就有,checked build enviremont,进这里以后就切到驱动所在的目录,然后build,就可以了,,,我这里在objchk/i386下就有uu.sys,,,,至于安装,,我还没按呢:>
程序的DriverEntry是入口点,,必须要有的,,里面有IoCreAtDrivce(),在这个程序里是在这里,msdn上说这个函数出现在DriverEntry或AddDrivce里,
The IoCreateDevice routine creates a device object for use by a driver.
NTSTATUS
IoCreateDevice(
IN PDRIVER_OBJECT DriverObject,
IN ULONG DeviceExtensionSize,
IN PUNICODE_STRING DeviceName OPTIONAL,
IN DEVICE_TYPE DeviceType,
IN ULONG DeviceCharacteristics,
IN BOOLEAN Exclusive,
OUT PDEVICE_OBJECT *DeviceObject
);
Parameters
DriverObject
Pointer to the driver object for the caller. Each driver receives a pointer to its driver object in a parameter to its DriverEntry routine. WDM function and filter drivers also receive a driver object pointer in their AddDevice routines.
DeviceExtensionSize
Specifies the driver-determined number of bytes to be allocated for the device extension of the device object. The internal structure of the device extension is driver-defined. For more information about device extensions, see Device Extensions.
DeviceName
Optionally points to a buffer containing a zero-terminated Unicode string that names the device object. The string must be a full path name. WDM filter and function drivers do not name their device objects. For more information, see Named Device Objects.
DeviceType
Specifies one of the system-defined FILE_DEVICE_XXX constants that indicate the type of device (such as FILE_DEVICE_DISK, FILE_DEVICE_KEYBOARD, etc.) or a vendor-defined value for a new type of device. For more information, see Specifying Device Types.
DeviceCharacteristics
Specifies one or more system-defined constants, ORed together, that provide additional information about the driver's device. For a list of possible device characteristics, see DEVICE_OBJECT. For more information on how to specify device characteristics, see Specifying Device Characteristics. Most drivers specify FILE_DEVICE_SECURE_OPEN for this parameter.
Exclusive
Reserved for system use. Drivers set this parameter to FALSE.
DeviceObject
Pointer to a variable that receives a pointer to the newly created DEVICE_OBJECT structure. The DEVICE_OBJECT structure is allocated from nonpaged pool.
Return Value
IoCreateDevice returns STATUS_SUCCESS on success, or the appropriate NTSTATUS error code on failure. A partial list of the failure codes returned by this function include:
STATUS_INSUFFICIENT_RESOURCES
STATUS_OBJECT_NAME_EXISTS
STATUS_OBJECT_NAME_COLLISION
Headers
Declared in wdm.h and ntddk.h. Include wdm.h or ntddk.h.
Comments
IoCreateDevice creates a device object and returns a pointer to the object. The caller is responsible for deleting the object when it is no longer needed by calling IoDeleteDevice.
IoCreateDevice can only be used to create an unnamed device object, or a named device object for which a security descriptor is set by an INF file. Otherwise, drivers must use IoCreateDeviceSecure to create named device objects. For more information, see Creating a Device Object. The caller is responsible for setting certain members of the returned device object. For more information, see Initializing a Device Object and the device-type-specific documentation for your device.
Be careful to specify the DeviceType and DeviceCharacteristics values in the correct parameters. Both parameters use system-defined FILE_XXX constants and some driver writers specify the values in the wrong parameters by mistake.
Device objects for disks, tapes, CD-ROMs, and RAM disks are given a Volume Parameter Block (VPB) that is initialized to indicate that the volume has never been mounted on the device.
If a driver's call to IoCreateDevice returns an error, the driver should release any resources that it allocated for that device.
Callers of IoCreateDevice must be running at IRQL < DISPATCH_LEVEL.
See Also
DEVICE_OBJECT, IoAttachDevice, IoAttachDeviceToDeviceStack, IoCreateDeviceSecure, IoCreateSymbolicLink, IoDeleteDevice
其中第3个参数DrivceNAme说WDM filter and function drivers do not name their device objects.如果一起名字,那么在其他的驱动里都可以通过这个名字来用这个object,,,msdn里有一段
A non-WDM driver must explicitly specify a name for any named device objects. The driver must create at least one named device object in the
/Device object directory to receive I/O requests. The driver specifies the device name as the
DeviceName parameter to
IoCreateDeviceSecure when creating the device object.
不知道non-WDM driver是指什么,,什么才是WDM driver-onlu
Some device Objects do not represent physicAl devices , A SoftwAre-only driver ,which hAndles I/O requests but does not pAss those requests to hArdwAre,still must creAte A device Object to represent tArget of its operAtions
IoCreateSymbolicLink是为了能在用户模式下通过CreAtFile来调用这个驱动
比如像这段汇编一样调用
;---------------------------------------------------------------
;Load the service /driver
;---------------------------------------------------------------
invoke OpenService,hScManager,ADDR ServiceName,SERVICE_ALL_ACCESS
.IF eax != 0
mov hService,eax
;--------------------------------------------------
;Start the service to set the service to the running
;state. StartService will call the DriverEntry procedure
;--------------------------------------------------
invoke StartService,hService,0,0
.IF eax != 0
;---------------------------------------------------
;Obtain a handle to the loaded driver for DeviceIoControl
;interface communcation
;---------------------------------------------------
invoke CreateFile,ADDR DriverPath ,GENERIC_READ or GENERIC_WRITE,0,0,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0
.IF eax != INVALID_HANDLE_VALUE
mov hDriver, eax
.ELSE
invoke MessageBoxA,NULL,ADDR lpMsgFileErrorText,ADDR lpMsgErrorTitle,MB_OK
jmp file_error ;CreateFile error
.ENDIF
;--------------------------------------------------
;Send service request SERVICE_SAY_HELLO
;--------------------------------------------------
invoke DeviceIoControl,hDriver,SERVICE_SAY_HELLO,0,0,ADDR lpOutBuffer,256,ADDR BytesReturned,0
mov edi,dword ptr lpOutBuffer