marco_xu
驱动牛犊
驱动牛犊
  • 注册日期2007-11-01
  • 最后登录2009-02-04
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望3点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
阅读:12298回复:5

调用ObRegisterCallbacks()时候遇到的问题

楼主#
更多 发布于:2007-11-01 22:59
我最近得到了wdk6001,尝试在64位vista sp1上加载我的驱动

当驱动接收到ioctl后,直接调用ObRegisterCallbacks,但是得到的返回值是0xC0000022(ACCESS_DENIED).

我的驱动是经过合法数字签名的,另外也从micrisoft申请了私有的altitude,有那位大侠知道可能是什么原因导致我得这样的返回结果?

代码如下〉

SYSTEM_VERSION    g_OsVer;
PVOID    *g_hProcCreateHandle;


//
//    PRE OPERATION
//
OB_PREOP_CALLBACK_STATUS    PreProcCreateRoutine(
                                                 __in    PVOID    RegistrationContext,
                                                 __inout    POB_PRE_OPERATION_INFORMATION    OperationInformation
                                                 )
{
    OB_PRE_OPERATION_INFORMATION    OpInfo;

    KDPRINT(("PreProcCreateRoutine()"));

    return    OB_PREOP_SUCCESS;
}


//
//    POST OPERATION
//
VOID    PostProcCreateRoutine(    __in    PVOID    RegistrationContext,
                            __in    POB_POST_OPERATION_INFORMATION    OperationInformation)
{
    KDPRINT(("PostProcCreateRoutine."));
}



//
//    REGISTE CALLBACK FUNCTION
//
NTSTATUS    RegisteCallbackFunction()
{
    NTSTATUS    ntStatus = STATUS_SUCCESS;
    
    UNICODE_STRING Altitude;

    USHORT    filterVersion = ObGetFilterVersion();
    USHORT    registrationCount = 2;

    POB_OPERATION_REGISTRATION    ProcCreateOperation;
    POB_CALLBACK_REGISTRATION    ProcCreateCallBack;

    REG_CONTEXT    *hRegistrationContext;
    hRegistrationContext = MALLOC(sizeof(REG_CONTEXT));
    hRegistrationContext->ulIndex = 1;

    ProcCreateOperation = MALLOC(sizeof(OB_OPERATION_REGISTRATION));
    ProcCreateCallBack = MALLOC(sizeof(OB_CALLBACK_REGISTRATION));

    if (filterVersion == OB_FLT_REGISTRATION_VERSION)
    {
        KDPRINT(("Filter Version is correct."));

        ProcCreateOperation->ObjectType = PsProcessType;
        ProcCreateOperation->Operations = OB_OPERATION_HANDLE_CREATE;
        ProcCreateOperation->PreOperation = PreProcCreateRoutine;
        ProcCreateOperation->PostOperation = PostProcCreateRoutine;

        ProcCreateCallBack->Version = OB_FLT_REGISTRATION_VERSION;
        ProcCreateCallBack->OperationRegistrationCount = registrationCount;
        
        RtlInitUnicodeString(&Altitude, L"xxxxxx");
        ProcCreateCallBack->Altitude = Altitude;



        ProcCreateCallBack->RegistrationContext = hRegistrationContext;
        ProcCreateCallBack->OperationRegistration = ProcCreateOperation;

        ntStatus = ObRegisterCallbacks(ProcCreateCallBack, g_hProcCreateHandle);
        if (ntStatus == STATUS_SUCCESS)
        {
            KDPRINT(("Register Callback Function Successful......"));
        } else {
            if (ntStatus == STATUS_FLT_INSTANCE_ALTITUDE_COLLISION)
            {
                KDPRINT(("Status Filter Instance Altitude Collision"));
            }
            if (ntStatus == STATUS_INVALID_PARAMETER)
            {
                KDPRINT(("Status Invalid Parameter"));
            }
            if (ntStatus == STATUS_INSUFFICIENT_RESOURCES )
            {
                KDPRINT(("Status Allocate Memory Failed."));
            }
            
            KDPRINT(("Register Callback Function Failed with 0x%08x", ntStatus));
        }

    } else {
        KDPRINT(("Filter Version is not supported. "));
    }

    return    ntStatus;
}



//
//    FREE PROC FILTER
//
NTSTATUS    FreeProcFilter()
{
    ObUnRegisterCallbacks(g_hProcCreateHandle);

    return    STATUS_SUCCESS;
}



//
//    INIT PROC FILTER
//
NTSTATUS    InitProcFilter()
{
    BOOLEAN    bContinue = FALSE;

    if (GetSystemVersion(&g_OsVer) == STATUS_SUCCESS)
    {
        KDPRINT((    "SystemVersion :: MajorVersion = %d, MinorVersion = %d, BuildNumber = %d",
                    g_OsVer.ulMajorVersion,
                    g_OsVer.ulMinorVersion,
                    g_OsVer.ulBuildNumber));

        if (g_OsVer.ulMajorVersion == 6 && g_OsVer.ulMinorVersion == 0)
        {
            KDPRINT(("Windows Vista Detected......"));
            if (g_OsVer.ulBuildNumber >= 6000)
            {
                KDPRINT(("Build is release......"));
                if (g_OsVer.ulBuildNumber >= 6001)
                {
                    KDPRINT(("Widnows Vista SP1 Detected......"));
                    bContinue = TRUE;
                } else {
                    KDPRINT(("WDK version is not supported......"));
                }
            } else {
                KDPRINT(("Version is not supported......"));
            }
        }        
    }

    if (bContinue)
    {
        if (RegisteCallbackFunction() == STATUS_SUCCESS)
        {
            KDPRINT(("Register Callback Function Successfully..."));
            bInitProcFilter = TRUE;
        }
    }

    return    STATUS_SUCCESS;
}



//
//    IOCTL
//
NTSTATUS    DoDeviceIoControl(IN    PDEVICE_OBJECT    pDriverObject,    IN    PIRP    pIrp)
{
    NTSTATUS    ntStatus = STATUS_SUCCESS;
    PIO_STACK_LOCATION    irpStack = IoGetCurrentIrpStackLocation(pIrp);
    ULONG        ulIoctlCode;
    
    ulIoctlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
    switch(ulIoctlCode)
    {
    case    IOCTL_REGISTER_CALLBACK:
        InitProcFilter();
        break;

    case    IOCTL_UNREGISTER_CALLBACK:
        FreeProcFilter();
        break;

    default:
        break;
    }

    return    ntStatus;
}
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
沙发#
发布于:2007-11-02 09:24
你的程序能编译通过吗??
PVOID    g_hProcCreateHandle = NULL;
ntStatus = ObRegisterCallbacks(ProcCreateCallBack, &g_hProcCreateHandle);
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
板凳#
发布于:2007-11-02 09:32
顺便查到点东西一起贴上来,看来WDK6001加了不少好东西,哪里能下到?MSDN里好象没有?
New Object Manager Filtering APIs
The new bits of the WDK have been released, and it seems that finally, we are starting to see a glimpse of some of the new filtering technologies that were promised in Vista SP1 to help with incompatibilities due to PatchGuard. Although Vista added powerful Registry filtering support on top of the existing File filtering architecture, hooking some native calls would still have been necessary in order to filter other kinds of system behaviour. The first which seems to have been addressed are handles, and Vista SP1 now supports Object Manager Filters.

Currently, only create and duplicate can be filtered, but the ability for both pre and post notifications exist. As with the new filter model, Object Manager Filters also support Altitudes, and are fully versionned. Unfortunately, this new set of APIs seems rather disappointing to me. For starters, this functionality was already available, even behind Patchguard’s back, through native Object Manager callbacks present in the OBJECT_TYPE’s ObjectTypeInitializer structure which contains all the callbacks for the object type. This interface seems to do nothing more but expose in a more public and accessible way the same ObCreateMethod interface that has existed since NT4, except that it only works for create and duplicate (while the internal interface allows for open and inherit as well).

Nevertheless, this new filtering mechanism is clearly written to be extensible for other Object Manager actions, so hopefully we’ll see some new improvements before SP1 actually ships. For the curious, here are some of the new toys to play with:

//
// Registration version for Vista SP1 and Windows Server 2007
//
#define OB_FLT_REGISTRATION_VERSION_0100  0×0100

//
// This value should be used by filters for registration
//
#define OB_FLT_REGISTRATION_VERSION OB_FLT_REGISTRATION_VERSION_0100

typedef ULONG OB_OPERATION;

#define OB_OPERATION_HANDLE_CREATE              0×00000001
#define OB_OPERATION_HANDLE_DUPLICATE           0×00000002

typedef struct _OB_PRE_CREATE_HANDLE_INFORMATION {
    __inout ACCESS_MASK         DesiredAccess;
    __in ACCESS_MASK            OriginalDesiredAccess;
} OB_PRE_CREATE_HANDLE_INFORMATION, *POB_PRE_CREATE_HANDLE_INFORMATION;

typedef struct _OB_PRE_DUPLICATE_HANDLE_INFORMATION {
    __inout ACCESS_MASK         DesiredAccess;
    __in ACCESS_MASK            OriginalDesiredAccess;
    __in PVOID                  SourceProcess;
    __in PVOID                  TargetProcess;
} OB_PRE_DUPLICATE_HANDLE_INFORMATION, * POB_PRE_DUPLICATE_HANDLE_INFORMATION;

typedef union _OB_PRE_OPERATION_PARAMETERS {
    __inout OB_PRE_CREATE_HANDLE_INFORMATION        CreateHandleInformation;
    __inout OB_PRE_DUPLICATE_HANDLE_INFORMATION     DuplicateHandleInformation;
} OB_PRE_OPERATION_PARAMETERS, *POB_PRE_OPERATION_PARAMETERS;

typedef struct _OB_PRE_OPERATION_INFORMATION {
    __in OB_OPERATION           Operation;
    union {
        __in ULONG Flags;
        struct {
            __in ULONG KernelHandle:1;
            __in ULONG Reserved:31;
        };
    };
    __in PVOID                         Object;
    __in POBJECT_TYPE                  ObjectType;
    __out PVOID                        CallContext;
    __in POB_PRE_OPERATION_PARAMETERS  Parameters;
} OB_PRE_OPERATION_INFORMATION, *POB_PRE_OPERATION_INFORMATION;

typedef struct _OB_POST_CREATE_HANDLE_INFORMATION {
    __in ACCESS_MASK            GrantedAccess;
} OB_POST_CREATE_HANDLE_INFORMATION, *POB_POST_CREATE_HANDLE_INFORMATION;

typedef struct _OB_POST_DUPLICATE_HANDLE_INFORMATION {
    __in ACCESS_MASK            GrantedAccess;
} OB_POST_DUPLICATE_HANDLE_INFORMATION, * POB_POST_DUPLICATE_HANDLE_INFORMATION;

typedef union _OB_POST_OPERATION_PARAMETERS {
    __in OB_POST_CREATE_HANDLE_INFORMATION       CreateHandleInformation;
    __in OB_POST_DUPLICATE_HANDLE_INFORMATION    DuplicateHandleInformation;
} OB_POST_OPERATION_PARAMETERS, *POB_POST_OPERATION_PARAMETERS;

typedef struct _OB_POST_OPERATION_INFORMATION {
    __in OB_OPERATION  Operation;
    union {
        __in ULONG Flags;
        struct {
            __in ULONG KernelHandle:1;
            __in ULONG Reserved:31;
        };
    };
    __in PVOID                          Object;
    __in POBJECT_TYPE                   ObjectType;
    __in PVOID                          CallContext;
    __in NTSTATUS                       ReturnStatus;
    __in POB_POST_OPERATION_PARAMETERS  Parameters;
} OB_POST_OPERATION_INFORMATION,*POB_POST_OPERATION_INFORMATION;

typedef enum _OB_PREOP_CALLBACK_STATUS {
    OB_PREOP_SUCCESS
} OB_PREOP_CALLBACK_STATUS, *POB_PREOP_CALLBACK_STATUS;

typedef OB_PREOP_CALLBACK_STATUS
(*POB_PRE_OPERATION_CALLBACK) (
    __in PVOID RegistrationContext,
    __inout POB_PRE_OPERATION_INFORMATION OperationInformation
    );

typedef VOID
(*POB_POST_OPERATION_CALLBACK) (
    __in PVOID RegistrationContext,
    __in POB_POST_OPERATION_INFORMATION OperationInformation
    );

typedef struct _OB_OPERATION_REGISTRATION {
    __in POBJECT_TYPE                *ObjectType;
    __in OB_OPERATION                Operations;
    __in POB_PRE_OPERATION_CALLBACK  PreOperation;
    __in POB_POST_OPERATION_CALLBACK PostOperation;
} OB_OPERATION_REGISTRATION, *POB_OPERATION_REGISTRATION;

typedef struct _OB_CALLBACK_REGISTRATION {
    __in USHORT                     Version;
    __in USHORT                     OperationRegistrationCount;
    __in UNICODE_STRING             Altitude;
    __in PVOID                      RegistrationContext;
    __in OB_OPERATION_REGISTRATION  *OperationRegistration;
} OB_CALLBACK_REGISTRATION, *POB_CALLBACK_REGISTRATION;

#if (NTDDI_VERSION >= NTDDI_VISTASP1)
NTKERNELAPI
NTSTATUS
ObRegisterCallbacks (
    __in POB_CALLBACK_REGISTRATION CallbackRegistration,
    __deref_out PVOID *RegistrationHandle
    );

NTKERNELAPI
VOID
ObUnRegisterCallbacks (
    __in PVOID RegistrationHandle
    );

NTKERNELAPI
USHORT
ObGetFilterVersion ();
#endif
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
marco_xu
驱动牛犊
驱动牛犊
  • 注册日期2007-11-01
  • 最后登录2009-02-04
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望3点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
地板#
发布于:2007-11-02 15:19
引用第1楼wowocock于2007-11-02 09:24发表的  :
你的程序能编译通过吗??
PVOID    g_hProcCreateHandle = NULL;
ntStatus = ObRegisterCallbacks(ProcCreateCallBack, &g_hProcCreateHandle);

贴错了,反了,不好意思
ntStatus = ObRegisterCallbacks(&ProcCreateCallBack, g_hProcCreateHandle);[/quote]
编译没有问题,
bigbian
驱动牛犊
驱动牛犊
  • 注册日期2003-08-23
  • 最后登录2013-01-24
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望74点
  • 贡献值0点
  • 好评度24点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2008-02-09 23:28
目前还没有出来正式版本的vista sp1,win2008,你做的研究只能是了解性的,因为那些内核对象回调的代码微软不一定放开了。
做人要厚道
bigbian
驱动牛犊
驱动牛犊
  • 注册日期2003-08-23
  • 最后登录2013-01-24
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望74点
  • 贡献值0点
  • 好评度24点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2008-03-03 16:00
摘自某文档
To reduce the chance of misuse of the APIs by malicious software, several requirements will need to be satisfied in order to utilize the API, and several constraints will be placed on the level of filtering possible in the API.


Kernel mode software that is using the new API must be digitally signed, on 32-bit and 64-bit systems, which enables identification and some degree of integrity.  Likewise, if there is user mode code that configures or provides policy to kernel mode software, it too must be digitally signed.  The code needs to be digitally signed consistent with the Authenticode signing procedures for mandatory driver signing on x64 platforms.  This process does not currently require the usage of WHQL for certification purposes -- the ISV may sign their own code without submitting it to Microsoft.
•    All ISV kernel and user mode modules must be linked with the /integritycheck flag set at link time.  This will cause the memory manager to enforce a signature check at load time for the referenced code.  This link.exe setting is present in recent versions of the Microsoft Visual Studio? linker.  If the ISV is using alternate tools to link or edit their produced binaries, this flag setting has the effect of setting (ON) IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY    (0x0800)   in the image PE header OptionalHeader.DllCharacteristics field.
•    Digitally signed user mode modules must have cryptographic per-page hash catalogs.  These are generated using the /PH command-line setting to the signtool utility.
•    The following link contains more information on the code-signing process, which is already mandatory for kernel mode software that loads on x64 based systems: http://www.microsoft.com/whdc/winlogo/drvsign/drvsign.mspx

If ISVs employ a user mode system service that is used to configure or control kernel mode software employing the new API, that system service must utilize the new Windows Service Hardening framework introduced in Microsoft Windows Vista?.  This will allow the service to employ least-privilege programming principals, in addition to allowing the ISV to govern who is granted access to service/driver specific resources.  For example, the Windows Service Hardening framework can be used to enforce that only the ISV provided user mode service has access to a driver object surfacing IOCTL interfaces.
•    The microsoft.com site has information on the new service hardening framework, as does the following whitepaper: http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/Vista_Services.doc
Any user mode system services should also be digitally signed.

ISV supplied callback function entry points must reside within valid code segments in the ISV provided digitally signed driver.  It is not permissible to provide callback addresses that reside in dynamically allocated memory.


For OB filtering the proposed design allows waiting on and signaling events; it is critical that any OB calls are done in the separate thread outside of the callout.  The callout can synchronize using an event but note that lengthy synchronous waits due to extensive processing on worker threads will be a delay in the application/system performance. ISVs should also consider using timeout based wait operations in the callback. To avoid issues with deadlocking, care should be taken to minimize the amount of processing done in the callout directly.  For cases where the processing requires waiting on state changes (e.g, polling for policy changes), it should be offloaded to a user mode service and the callout should continue asynchronously.

It is the responsibility of the ISV to determine their preferred behavior in error conditions.  For example, if a low-memory condition is encountered, the ISV may choose to fail secure or fail open (where on detecting an error an action may be allowed or deferred to a later time).  Note the operating system will not define this, as ISV requirements around failure handling may differ, or may be based on security policy.  For the purposes of illustration, the ISV may encounter a low memory condition during their callback processes. The following two cases indicate possible handling modes:

1.    The ISV chooses to fail secure.  For Ob callback processing, the ISV may choose to filter out specific access bits.  For Ps callback processing, the ISV may choose to block the process creation operation.
2.    The ISV chooses to fail open.  In this particular case, the ISV does not filter or block the operation, and may instead opt to log an event or alert the user.  This alerting may be queued/deferred until the low-memory condition subsides.    

Programs which are using the API must be discoverable by the administrator.  A standard administrative uninstall procedure needs to be supported.  The code needs to be visible during kernel module enumeration operations.

It must not be possible to create a situation where processes or resources are completely invisible to the administrator.  For example, all processes should be visible in the Task Manager.

It must be possible to perform security scanning and compliance checking operations (e.g., anti-virus scanning, integrity checking, etc.) against code using the new APIs, as well as processes/code that is being influenced by the new API.

Future enhancements to the APIs may come at a later date than Windows Server 2008, including requirements that higher assurance (e.g., EV code signing) certificates must be used to sign code, as well as additional code signing enforcement and associated requirements for security software.  ISVs will be notified of any new requirements and have an opportunity to comment before they are introduced.

Additional API usage criteria may also be outlined in the “Kernel Evaluation Criteria” document that is published by Microsoft.
做人要厚道
游客

返回顶部