直接扔关键代码,不想写太多的说明,本来这些代码也只是副产品,眼尖的应该能看出来这些代码的来处和去处。
===============
PACCESS_ALLOWED_ACE
GetAceFromAcl(
IN PACL Dacl,
IN ULONG AceIndex
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
USHORT i = 0;
PACCESS_ALLOWED_ACE Ace = NULL;
if (Dacl && AceIndex < Dacl->AceCount)
{
for (Ace = FirstAce(Dacl); i < AceIndex; Ace = NextAce(Ace))
{
if (Ace >= (PACCESS_ALLOWED_ACE)((PUCHAR)Dacl + Dacl->AclSize))
{
break;
}
++ i;
}
if (i == AceIndex)
{
return Ace;
}
}
return NULL;
}
BOOLEAN
NmCheckDaclForGroupSid(
IN PACL Dacl
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
USHORT i = 0;
USHORT gSidOffset, cSidOffset;
BOOLEAN result = FALSE;
PACCESS_ALLOWED_ACE pACE = NULL;
SIZE_T retLong;
if (g_GroupAce->Header.AceSize >= (USHORT)(sizeof(ACCESS_ALLOWED_ACE)))
{
gSidOffset = g_GroupAce->Header.AceSize -
(USHORT)(sizeof(ACCESS_ALLOWED_ACE));
if (Dacl->AceCount)
{
do
{
pACE = GetAceFromAcl(Dacl, i);
if (pACE)
{
cSidOffset = pACE->Header.AceSize -
(USHORT)(sizeof(ACCESS_ALLOWED_ACE));
if (gSidOffset == cSidOffset)
{
retLong = RtlCompareMemory(
&(pACE->SidStart),
&(g_GroupAce->SidStart),
cSidOffset
);
result = (cSidOffset == retLong);
if (result == TRUE)
{
return result;
}
}
}
++ i;
} while (i < Dacl->AceCount);
}
}
return result;
}
BOOLEAN
AddAceToAcl(
IN PACL NewAcl,
IN PACCESS_ALLOWED_ACE toAddAce
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
USHORT i = 0;
PACCESS_ALLOWED_ACE Ace = FirstAce(NewAcl);
if (NewAcl && toAddAce)
{
if (NewAcl->AceCount)
{
for (NOTHING; i < NewAcl->AceCount; Ace = NextAce(Ace))
{
if (Ace >= (PACCESS_ALLOWED_ACE)((PUCHAR)NewAcl + NewAcl->AclSize))
{
break;
}
++ i;
}
}
if ((PACCESS_ALLOWED_ACE)((PUCHAR)Ace + toAddAce->Header.AceSize) >
(PACCESS_ALLOWED_ACE)((PUCHAR)NewAcl + NewAcl->AclSize))
{
return FALSE;
}
else
{
NdisMoveMemory(
Ace,
toAddAce,
toAddAce->Header.AceSize
);
NewAcl->AceCount = i + 1;
}
}
return TRUE;
}
NDIS_STATUS
NmModifyDacl(
IN PACL oldDacl,
OUT PACL* NewDacl
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
NDIS_STATUS result = NDIS_STATUS_SUCCESS;
USHORT tSize;
PACL tmpDacl = NULL;
USHORT i = 0;
PACCESS_DENIED_ACE pdACE = NULL;
PACCESS_ALLOWED_ACE paACE = NULL;
if (oldDacl)
{
tSize = oldDacl->AclSize + g_GroupAce->Header.AceSize;
tmpDacl = (PACL)ExAllocatePoolWithTag(
NonPagedPool,
tSize,
'dnTF'
);
if (tmpDacl)
{
tmpDacl->AclRevision = oldDacl->AclRevision;
tmpDacl->Sbz1 = oldDacl->Sbz1;
tmpDacl->AceCount = 0;
tmpDacl->AclSize = tSize;
tmpDacl->Sbz2 = oldDacl->Sbz2;
if (oldDacl->AceCount)
{
do
{
pdACE = (PACCESS_DENIED_ACE)GetAceFromAcl(
oldDacl,
i
);
if (pdACE->Header.AceType != ACCESS_DENIED_ACE_TYPE)
{
break;
}
AddAceToAcl(tmpDacl, (PACCESS_ALLOWED_ACE)pdACE);
++ i;
} while (i < oldDacl->AceCount);
}
AddAceToAcl(tmpDacl, g_GroupAce);
while(i < oldDacl->AceCount)
{
paACE = GetAceFromAcl(oldDacl, i);
AddAceToAcl(tmpDacl, (PACCESS_ALLOWED_ACE)paACE);
++ i;
}
*NewDacl= tmpDacl;
}
}
return result;
}
NDIS_STATUS
NmAddGroupAccessAce(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
PSECURITY_DESCRIPTOR NewSecurityDescriptor = NULL;
ULONG csize = sizeof(SECURITY_DESCRIPTOR);
PACL NewDdcl = NULL;
HANDLE Handle = NULL;
BOOLEAN DaclPresent, DaclDefaulted;
PACL Dacl = NULL;
if (DeviceObject && g_GroupAce)
{
Status = ObOpenObjectByPointer(
DeviceObject,
OBJ_KERNEL_HANDLE,
NULL,
WRITE_DAC,
0,
0,
&Handle
);
if (Status == NDIS_STATUS_SUCCESS)
{
SecurityDescriptor = DeviceObject->SecurityDescriptor;
Status = RtlGetDaclSecurityDescriptor(
SecurityDescriptor,
&DaclPresent,
&Dacl,
&DaclDefaulted
);
if (Status == NDIS_STATUS_SUCCESS)
{
ASSERT(DaclPresent);
ASSERT(Dacl != NULL);
if (NmCheckDaclForGroupSid(Dacl) != TRUE)
{
csize = RtlLengthSecurityDescriptor(SecurityDescriptor);
NewSecurityDescriptor = ExAllocatePoolWithTag(
NonPagedPool,
g_GroupAce->Header.AceSize + csize,
'dnTF'
);
if (NewSecurityDescriptor)
{
RtlCreateSecurityDescriptor(
NewSecurityDescriptor,
SECURITY_DESCRIPTOR_REVISION
);
Status = NmModifyDacl(
Dacl,
&NewDdcl
);
if (Status == NDIS_STATUS_SUCCESS)
{
Status = RtlSetDaclSecurityDescriptor(
NewSecurityDescriptor,
TRUE,
NewDdcl,
FALSE
);
if (Status == NDIS_STATUS_SUCCESS)
{
Status = ZwSetSecurityObject(
Handle,
DACL_SECURITY_INFORMATION,
NewSecurityDescriptor
);
}
}
}
}
}
}
if (Handle)
{
ZwClose(Handle);
}
if (NewSecurityDescriptor)
{
ExFreePoolWithTag(NewSecurityDescriptor, 'dnTF');
}
if (NewDdcl)
{
ExFreePoolWithTag(NewDdcl, 'dnTF');
}
}
return Status;
}
===============
在RegisterDevice之后加上即可,对于g_GroupAce,这个查询注册表或者自己获取,这些都是因时而异。
我这里是需要从注册表读过来的,然后加上去的:
===============
PACCESS_ALLOWED_ACE g_GroupAce = NULL;
//...省略...
InitializeObjectAttributes(
&ObjectAttributes,
RegistryPath,
OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
Status = ZwOpenKey(
&hHandle,
KEY_READ,
&ObjectAttributes
);
if (Status == STATUS_SUCCESS)
{
RtlInitUnicodeString(&DestinationString, L"GroupSid");
Status = ZwQueryValueKey(
hHandle,
&DestinationString,
KeyValueFullInformation,
0,
0,
&ResultLength
);
if (Status == STATUS_BUFFER_OVERFLOW ||
Status == STATUS_BUFFER_TOO_SMALL)
{
pBuffer = (PKEY_VALUE_FULL_INFORMATION)ExAllocatePoolWithTag(
NonPagedPool,
ResultLength,
'dnTF'
);
if (pBuffer)
{
Status = ZwQueryValueKey(
hHandle,
&DestinationString,
KeyValueFullInformation,
pBuffer,
ResultLength,
&ResultLength
);
if (Status == STATUS_SUCCESS)
{
g_GroupAce = (PACCESS_ALLOWED_ACE)ExAllocatePoolWithTag(
NonPagedPool,
pBuffer->DataLength + sizeof(ACCESS_ALLOWED_ACE),
'gamn'
);
if (g_GroupAce)
{
NdisZeroMemory(
g_GroupAce,
pBuffer->DataLength + sizeof(ACCESS_ALLOWED_ACE)
);
g_GroupAce->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
g_GroupAce->Header.AceFlags = 0;
g_GroupAce->Header.AceSize =
(USHORT)(pBuffer->DataLength +
sizeof(ACCESS_ALLOWED_ACE));
g_GroupAce->Mask = SYNCHRONIZE |
READ_CONTROL | FILE_READ_ATTRIBUTES |
FILE_READ_DATA | FILE_READ_EA;
NdisMoveMemory(
(PVOID)&(g_GroupAce->SidStart),
(PVOID)((PUCHAR)pBuffer + pBuffer->DataOffset),
pBuffer->DataLength
);
//...省略...
===============
PS: 排版很麻烦,我改了半天。下篇把这个工程的真正精华部分放上来大家探讨。