借鉴别人用DPC的思路,在虚拟机上前一二次加载驱动正常,能输出正确的ISR值,但第三次或者是第四次重新加载驱动...必蓝屏,主要是蓝在KeInsertQueueDpc (idtDpc, NULL, NULL)上.跟踪了下,每次此函数的输入参数idtDpc的各项值都是一样的,.不知道为何第三四次就蓝屏了..高手露两下沙..头疼阿..
#include <wdm.h>
#include <Ntddk.h>
typedef unsigned char P2C_U8;
typedef unsigned short P2C_U16;
typedef unsigned long P2C_U32;
#pragma pack (push, 1)
typedef struct P2C_IDTR_{
P2C_U16 Limit;
P2C_U32 Base;
} P2C_IDTR, *PP2C_IDTR;
#pragma pack (pop)
#pragma pack(push,1)
typedef struct P2C_IDT_ENTRY_{
P2C_U16 offset_low;
P2C_U16 selector;
P2C_U8 reserved;
P2C_U8 type:4;
P2C_U8 always:1;
P2C_U8 dpl:2;
P2C_U8 present:1;
P2C_U16 offset_high;
} P2C_IDTENTRY, *PP2C_IDTENTRY;
#pragma pack(pop)
typedef ULONG(_stdcall *KEQUERYACTIVEPROCESSORS)(void);
P2C_IDTR idtr;
KSPIN_LOCK idtLock;
ULONG CpuNumber = 0;
ULONG cpuID = 0;
ULONG OldISRaddress[128] ={0};
PP2C_IDTENTRY idtEntry;
void myidtDpc(PRKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
{
P2C_U16 offsetlow;
P2C_U16 offsethigh;
KIRQL idtIrql;
KeAcquireSpinLock (&idtLock, &idtIrql);
_asm sidt idtr
idtEntry = (PP2C_IDTENTRY)idtr.Base;
idtEntry += 0x93;
OldISRaddress[cpuID] = (P2C_U32) idtEntry->offset_high;
OldISRaddress[cpuID] = OldISRaddress[cpuID] << 16;
OldISRaddress[cpuID] |= (P2C_U32) idtEntry->offset_low;
DbgPrint(("Cpu[%d]KeyBoard ISR address:%x!\n"), cpuID, OldISRaddress[cpuID]);
cpuID++;
KeReleaseSpinLock (&idtLock, &idtIrql);
}
_declspec (naked) ULONG MyProcessorCounter(KAFFINITY BitMap)
{
_asm pushad
_asm pushfd
_asm mov eax,[esp+28h]
_asm xor ebx,ebx
_asm mov ecx, 20h
Next:
_asm shr eax,1
_asm jnc NotAdd
_asm add ebx,1
NotAdd:
_asm Loop Next
_asm mov [esp+20h],ebx
_asm popfd
_asm popad
_asm ret 4
}
NTSTATUS DispatchRoutine (PDEVICE_OBJECT DeviceObject, PIRP pIrp);
NTSTATUS Unload (PDRIVER_OBJECT DriverObject);
NTSTATUS DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING registerPath)
{
KAFFINITY Bitmap;
ULONG i;
UNICODE_STRING Routine;
KEQUERYACTIVEPROCESSORS myProcessorCount;
PRKDPC idtDpc = NULL;
PVOID temp =NULL;
NTSTATUS status;
PDEVICE_OBJECT DeviceObject;
status = IoCreateDevice (DriverObject, 0, NULL, FILE_DEVICE_UNKNOWN, NULL, FALSE, &DeviceObject);
if (!NT_SUCCESS(status))
{
return STATUS_UNSUCCESSFUL;
}
for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION+1; i++)
{
DriverObject->MajorFunction[i] = DispatchRoutine;
}
DriverObject->DriverUnload = Unload;
_asm int 3
RtlInitUnicodeString (&Routine, L"KeQueryActiveProcessors");
myProcessorCount = MmGetSystemRoutineAddress (&Routine);
KeInitializeSpinLock(&idtLock);
Bitmap = myProcessorCount();
CpuNumber = MyProcessorCounter(Bitmap);
idtDpc = (PRKDPC) ExAllocatePool (NonPagedPool, sizeof(KDPC)*CpuNumber);
if (idtDpc == NULL)
{
return STATUS_UNSUCCESSFUL;
}
temp = (PVOID)idtDpc;
for (i = 0; i < CpuNumber; i++)
{
KeInitializeDpc(idtDpc, (PKDEFERRED_ROUTINE) myidtDpc, NULL);
KeSetTargetProcessorDpc (idtDpc, i);
KeInsertQueueDpc (idtDpc, NULL, NULL);
idtDpc +=sizeof(KDPC);
}
while (cpuID != CpuNumber)
{
_asm nop
}
ExFreePool(temp);
return STATUS_SUCCESS;
}
NTSTATUS Unload (PDRIVER_OBJECT DriverObject)
{
PDEVICE_OBJECT pTargetDeviceObject = NULL,Temp = NULL;
pTargetDeviceObject = DriverObject->DeviceObject;
while (pTargetDeviceObject)
{
Temp = pTargetDeviceObject->NextDevice;
IoDeleteDevice(pTargetDeviceObject);
pTargetDeviceObject = Temp;
}
return STATUS_SUCCESS;
}
NTSTATUS DispatchRoutine (PDEVICE_OBJECT DeviceObject, PIRP pIrp)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
[课程]Android-CTF解题方法汇总!