2013年5月1日星期三

ExRegisterCallback.C

/*
文本就命名为:ExRegisterCallback.C吧!
made by correy
made at 2013.05.01
QQ:112426112
Email:kouleguan at hotmail dot com
Homepage:http://correy.webs.com

本文参考了msdn/wdk.
http://www.osronline.com/article.cfm?id=24
http://blog.csdn.net/svtanto/article/details/6255808
http://hi.baidu.com/sysnap/item/7ac898db93094e3be3108fff
http://hi.baidu.com/antbean1988/item/6c14a89205487ceb2816475f

具体的用途有不多说了,没有深究。
觉得很有用,以后再研究添加功能。
*/

#include <ntddk.h>

#define _In_
#define _Inout_
#define _Inout_opt_

PVOID CbRegistration;

DRIVER_UNLOAD Unload;
VOID Unload(__in PDRIVER_OBJECT DriverObject)
{
    if (CbRegistration) {
        ExUnregisterCallback(CbRegistration);//运行之后,对象还存在。可以用工具查看。
    }
}

//PCALLBACK_FUNCTION pcallback_function;
VOID pcallback_function  (IN PVOID CallbackContext, IN PVOID Argument1, IN PVOID Argument2)
{
    DbgPrint("停下来看看吧!\n");
    KdBreakPoint();
}

DRIVER_INITIALIZE DriverEntry;
NTSTATUS DriverEntry( __in struct _DRIVER_OBJECT  * DriverObject, __in PUNICODE_STRING  RegistryPath)
{
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    BOOLEAN b = 0;
    UNICODE_STRING CallbackName;
    OBJECT_ATTRIBUTES InitializedAttributes;
    PCALLBACK_OBJECT  PCallbackObject;

    KdBreakPoint();//#define KdBreakPoint() DbgBreakPoint()

    DriverObject->DriverUnload = Unload;  

    RtlInitUnicodeString(&CallbackName, L"\\Callback\\correy");

    InitializeObjectAttributes(&InitializedAttributes, &CallbackName, OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, NULL, NULL);

    status = ExCreateCallback(&PCallbackObject, &InitializedAttributes, TRUE, 0);//TRUE
    if(!NT_SUCCESS(status) )  {
        DbgPrint("ExCreateCallback failed 0x%0x\n", status);  
        return status;
    }

    //CbRegistration = (PCallbackObject, pcallback_function, NULL);//错误的书写格式,总是返回值为0。
    CbRegistration = ExRegisterCallback(PCallbackObject, pcallback_function, NULL);
    if(CbRegistration == 0)  {//如果已经注册成功,再此注册之前不成功运行ExUnregisterCallback,会返回值是0.
        DbgPrint("CbRegistration failed\n");  
        return STATUS_UNSUCCESSFUL;
    }

    ObDereferenceObject(PCallbackObject);

    ExNotifyCallback(PCallbackObject, NULL, NULL);//这个调用是测试。第一个参数加个&会导致:BugCheck A, {2c, 2, 0

    return status;//STATUS_SUCCESS
}

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

#include <ntifs.h>

/*
Using a System-Defined Callback Object
http://msdn.microsoft.com/en-us/library/windows/hardware/ff564933(v=vs.85).aspx

有如下内容:
The system defines three callback objects for driver use:
\Callback\SetSystemTime
\Callback\PowerState
\Callback\ProcessorAdd

Drivers that use the system time (for example, file system drivers) might register for the \Callback\SetSystemTime callback object.
This callback provides for notification when the system time changes.

......

To use a system-defined callback, a driver initializes an attribute block (InitializeObjectAttributes) with the callback's name,
then opens the callback object (ExCreateCallback), just as for a driver-defined callback.
The driver should not request that the callback object be created.

With the handle returned by ExCreateCallback, the driver calls ExRegisterCallback to register a notification routine,
passing a pointer to an arbitrary context and a pointer to its routine.
A driver can register its callback routine any time.
When the specified condition occurs, the system calls the registered callback routine at IRQL<=DISPATCH_LEVEL.

本文就是按照链接的说明以\Callback\SetSystemTime演示的。

made by correy
made at 2014.05.07
email:kouleguan at hotmail dot com
homepage:http://correy.webs.com
*/

PVOID CbRegistration;
PCALLBACK_OBJECT  PCallbackObject;

DRIVER_UNLOAD Unload;
VOID Unload(__in PDRIVER_OBJECT DriverObject)
{
    //When the driver no longer requires notification,
    //it should call ExUnregisterCallback to delete its callback routine from the list of registered callbacks and to remove its reference to the callback object.
    if (CbRegistration) {
        ExUnregisterCallback(CbRegistration);
    }
    ObDereferenceObject(PCallbackObject);
}

VOID pcallback_function  (IN PVOID CallbackContext, IN PVOID Argument1, IN PVOID Argument2)
    /*
    注意:IRQL<=DISPATCH_LEVEL,解决办法是加工作线程和同步对象。

    如果是:\Callback\SetSystemTime
    Argument1     Not used.
    Argument2     Not used.
    不过经观察:CallbackContext的都为0.
    */
{  
    DbgPrint("时间被修改了。\n");
    KdBreakPoint();
}

DRIVER_INITIALIZE DriverEntry;
NTSTATUS DriverEntry( __in struct _DRIVER_OBJECT  * DriverObject, __in PUNICODE_STRING  RegistryPath)
{
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    UNICODE_STRING CallbackName;
    OBJECT_ATTRIBUTES InitializedAttributes;  

    KdBreakPoint();

    DriverObject->DriverUnload = Unload;  

    RtlInitUnicodeString(&CallbackName, L"\\Callback\\SetSystemTime");
    InitializeObjectAttributes(&InitializedAttributes, &CallbackName, OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, NULL, NULL);
    status = ExCreateCallback(&PCallbackObject, &InitializedAttributes, TRUE, 0);//TRUE
    if(!NT_SUCCESS(status) )  {
        DbgPrint("ExCreateCallback failed 0x%0x\n", status);  
        return status;
    }

    CbRegistration = ExRegisterCallback(PCallbackObject, pcallback_function, NULL);
    if(CbRegistration == 0)  {
        DbgPrint("CbRegistration failed\n");
        ObDereferenceObject(PCallbackObject);
        return STATUS_UNSUCCESSFUL;
    }    

    return status;//STATUS_SUCCESS
}

没有评论:

发表评论