DriverEntry 创建一个命名的内核通知事件对象
HANDLE g_hEvent = NULL;
PKEVENT g_kEvent = NULL;
__debugbreak();
UNICODE_STRING usEventName = RTL_CONSTANT_STRING(L"\\BaseNamedObjects\\test_event");
g_kEvent = IoCreateNotificationEvent(&usEventName, &g_hEvent);
KeClearEvent(g_kEvent);
// 修改内核对象安全描述符
SetEventACL(g_hEvent);
DbgPrint("g_kEvent=%p g_hEvent=%p Name=%wZ \n",g_kEvent, g_hEvent, &usEventName);
用户层打开该对象,并创建线程,等待事件通知
HANDLE g_UserEvent = NULL;
DWORD WINAPI MyThreadFunction( LPVOID lpParam )
{
if(WAIT_OBJECT_0 == WaitForSingleObject(g_UserEvent, INFINITE))
{
printf("User Mode Thread Signaled.\n");
}
printf("Loop Thread Exited.\n");
return 0;
}
int main()
{
do
{
g_UserEvent = OpenEventA(SYNCHRONIZE, NULL, "Global\\test_event");
} while (!g_UserEvent);
HANDLE hThread = CreateThread(0, NULL, MyThreadFunction, NULL, 0, NULL);
printf("UserMode Loop Thread Wait for Kernel Event Siginal. hThread=%p g_UserEvent=%p\n",hThread, g_UserEvent);
}
此时用户层程序如果是普通用户权限,则打开Event失败,因为内核创建的对象,普通用户层是没有权限打开的
使用下面函数修改内核Event的安全描述符以后,加入SeAliasUsersSid,给普通用户也赋予权限,这样就可以打开内核的Event了,
NTSTATUS SetEventACL(HANDLE hObj)
{
ULONG uACLSize = 0;
PACL pACL = NULL;
SECURITY_DESCRIPTOR SecurityDesc = {0};
NTSTATUS Status = STATUS_UNSUCCESSFUL;
do
{
//
// Calculate how big our ACL needs to be support one ACE
// (in this case we'll use a predefined Se Export for local system as the SID)
//
uACLSize = sizeof(ACL);
uACLSize += RtlLengthSid(SeExports->SeLocalSystemSid);
uACLSize += RtlLengthSid(SeExports->SeAliasAdminsSid);
uACLSize += RtlLengthSid(SeExports->SeAliasUsersSid);
//
// Room for 3 ACEs (one for each SID above); note we don't
// include the end of the structure as we've accounted for that length in the SID lengths already.
//
uACLSize += 3 * FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart);
pACL = (PACL)ExAllocatePool(PagedPool, uACLSize);
if(pACL == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
Status = RtlCreateAcl(pACL, uACLSize, ACL_REVISION);
if(!NT_SUCCESS(Status))
{
break;
}
Status = RtlAddAccessAllowedAce(pACL, ACL_REVISION, GENERIC_ALL, SeExports->SeLocalSystemSid);
if(!NT_SUCCESS(Status))
{
break;
}
Status = RtlAddAccessAllowedAce(pACL, ACL_REVISION, GENERIC_ALL, SeExports->SeAliasAdminsSid);
if(!NT_SUCCESS(Status))
{
break;
}
Status = RtlAddAccessAllowedAce(pACL, ACL_REVISION, GENERIC_ALL, SeExports->SeAliasUsersSid);
if(!NT_SUCCESS(Status))
{
break;
}
//
// Create a SecurityDescriptor
//
Status = RtlCreateSecurityDescriptor(&SecurityDesc, SECURITY_DESCRIPTOR_REVISION);
if(!NT_SUCCESS(Status))
{
break;
}
//
// Associate the above pACL with the security descriptor
//
Status = RtlSetDaclSecurityDescriptor(&SecurityDesc, TRUE, pACL, FALSE);
if(!NT_SUCCESS(Status))
{
break;
}
//
// Set security on the object
//
Status = ZwSetSecurityObject(hObj, DACL_SECURITY_INFORMATION, &SecurityDesc);
if(!NT_SUCCESS(Status))
{
break;
}
} while (false);
if(pACL)
{
ExFreePool(pACL);
pACL = NULL;
}
return Status;
}
版权声明:本文为cssxn原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。