Windows 2000 下利用驱动修改IDT添加自己的中断

/ns/wz/sys/data/20020813022050.htm

Windows 2000 下利用驱动修改IDT添加自己的中断


Author: sinister
Email: sinister@whitecell.org
Homepage:http://www.whitecell.org

添加中断的DRIVE编译为DEBUG版,后用DriverMonitor加载,再
写一个应用程序并在其中调用相应的中断号,即可在DriverMonitor
中显示调用成功。下面是全部代码,错误之处还望各位指正。

以下代码在 Windows 2000 Service Pack 2 下测试通过。

AddMyInt.c


//********************************************************
// 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;
}


TestAddInt.c

int main(int argc, char* argv[])
{
_asm {
int 76h
}
return 0;
}