阅读:12299回复:5
调用ObRegisterCallbacks()时候遇到的问题
我最近得到了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; } |
|
沙发#
发布于: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. |
|
|
板凳#
发布于:2008-02-09 23:28
目前还没有出来正式版本的vista sp1,win2008,你做的研究只能是了解性的,因为那些内核对象回调的代码微软不一定放开了。
|
|
|
地板#
发布于:2007-11-02 15:19
引用第1楼wowocock于2007-11-02 09:24发表的 : 贴错了,反了,不好意思 ntStatus = ObRegisterCallbacks(&ProcCreateCallBack, g_hProcCreateHandle);[/quote] 编译没有问题, |
|
地下室#
发布于: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 |
|
|
5楼#
发布于:2007-11-02 09:24
你的程序能编译通过吗??
PVOID g_hProcCreateHandle = NULL; ntStatus = ObRegisterCallbacks(ProcCreateCallBack, &g_hProcCreateHandle); |
|
|