驱动内存异常
ProbeForRead | 探测内存是否可读 |
---|---|
ProbeForWrite | 探测内存是否可写 |
ExRaiseStatus | 指定状态代码触发异常 |
ExRaiseAccessViolation | 触发STATUS_ACCESS_VIOLATION异常(访问异常) |
ExRaiseDatatypeMisalignment | 触发STATUS_DATATYPE_MISALIGNMENT异常(数据类型异常) |
注意不要通过触发异常告诉你的调用者你在普通执行状态中的信息,你完全可以返回状态代码。应该尽量避免使用异常,因为堆栈回调机制非常消耗资源。
1.异常
//判断返回值是否正确
if (!NT_SUCCESS(status))
{
KdPrint(("返回值成功"));
}
else
{
KdPrint(("返回值失败"));
}
//判断驱动是否为挂起状态
if (status== STATUS_PENDING)
{
KdPrint(("返回值成功"));
}
else
{
KdPrint(("返回值失败"));
}
//判断 设备未就绪
if (status == STATUS_DEVICE_NOT_READY)
{
KdPrint(("返回值成功"));
}
else
{
KdPrint(("返回值失败"));
}
//严重异常
NTSTATUS status = STATUS_UNSUCCESSFUL;
2.异常捕获
- 异常处理方式一
#include <ntddk.h>
VOID Unload(IN PDRIVER_OBJECT pDriverObject)
{
//驱动卸载的时候显示
KdPrint(("Goodbye driver\n"));
}
extern "C" NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
PCHAR Buffer = NULL;
DriverObject->DriverUnload = Unload;
//驱动启动的时候显示
KdPrint(("Hello driver\n"));
__try
{
//内存写捕获
*Buffer = 'a';
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
KdPrint(("内存写异常码%x\n", GetExceptionCode()));
}
__try
{
//内存读捕获
KdPrint(("%d\n", *Buffer));
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
KdPrint(("内存读异常码%x\n", GetExceptionCode()));
}
__try
{
//是否可以读
ProbeForRead(Buffer, 4, 4);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
KdPrint(("ProbeForRead 异常码%x\n", GetExceptionCode()));
}
__try
{
//是否可以写
ProbeForWrite(Buffer, 4, 4);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
KdPrint(("ProbeForWrite异常码%x\n", GetExceptionCode()));
}
__try
{
//是否可以指定状态代码触发异常
ExRaiseStatus(STATUS_ACCESS_VIOLATION);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
KdPrint(("ExRaiseStatus异常码%x\n", GetExceptionCode()));
}
__try
{
//触发ExRaiseAccessViolation异常(内存访问文件的异常)
ExRaiseAccessViolation();
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
KdPrint(("ExRaiseAccessViolation异常码%x\n", GetExceptionCode()));
}
__try
{
//触发ExRaiseDatatypeMisalignment异常
ExRaiseDatatypeMisalignment();
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
KdPrint(("ExRaiseDatatypeMisalignment异常码%x\n", GetExceptionCode()));
}
return STATUS_SUCCESS;
}
由于ProbeForRead没有产生任何异常说明这个函数时不准确的,这里也容易被黑客攻击跳转详细原因
- 异常处理方式二
#include <ntddk.h>
VOID Unload(IN PDRIVER_OBJECT pDriverObject)
{
//驱动卸载的时候显示
KdPrint(("Goodbye driver\n"));
}
extern "C" NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
PCHAR Buffer = NULL;
LONG f1, f2, f3;
DriverObject->DriverUnload = Unload;
//驱动启动的时候显示
KdPrint(("Hello driver\n"));
f1 = 0;
f2 = 1;
f3 = 2;
__try
{
if (f1!=0)
{
KdPrint(("在f1\n"));
__leave;
}
if (f2 == 1)
{
KdPrint(("在f2\n"));
__leave;
}
if (f3 == 1)
{
KdPrint(("在f3\n"));
__leave;
}
}
__finally
{
KdPrint(("在finally\n"));
}
return STATUS_SUCCESS;
}
#include <ntddk.h>
VOID Unload(IN PDRIVER_OBJECT pDriverObject)
{
//驱动卸载的时候显示
KdPrint(("Goodbye driver\n"));
}
extern "C" NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
PCHAR Buffer = NULL;
LONG f1, f2, f3;
DriverObject->DriverUnload = Unload;
//驱动启动的时候显示
KdPrint(("Hello driver\n"));
f1 = 0;
f2 = 1;
f3 = 2;
__try
{
if (f1==0)
{
KdPrint(("在f1\n"));
return STATUS_SUCCESS;
}
if (f2 == 1)
{
KdPrint(("在f2\n"));
return STATUS_SUCCESS;
}
if (f3 == 1)
{
KdPrint(("在f3\n"));
return STATUS_SUCCESS;
}
}
__finally
{
KdPrint(("在finally\n"));
}
return STATUS_SUCCESS;
}