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