命名内核对象有一种问题:任何程序都可以创建一个命名对象,这样如果某个程序要实现单例运行而创建了一个内核对象,这种情况下另一程序也创建了同名的内核对象时,该单例程序就无法正常运行了。这是DoS攻击的一种。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
在Vista中有一种机制使得用户创建的命名内核对象永远不会和其它程序创建的对象冲突,要使用定制的前缀并把它作为人的私有命名空间,如Global和Local,服务进程会确保为内核对象定义一边界描述符来保护命名空间。
下面是检查实例的代码:
void
CheckInstances()

{//检查实例
//Createtheboundarydescriptor
g_hBoundary=CreateBoundaryDescriptor(g_szBoundary,0);

//CreateaSIDcorrespondingtotheLocalAdministratorgroup
BYTElocalAdminSID[SECURITY_MAX_SID_SIZE];
PSIDpLocalAdminSID=&localAdminSID;
DWORDcbSID=sizeof(localAdminSID);
if(!CreateWellKnownSid(
WinBuiltinAdministratorsSid,NULL,pLocalAdminSID,&cbSID)

)
{
AddText(TEXT("AddSIDToBoundaryDescriptorfailed:%u/r/n"),
GetLastError());
return;
}

//AssociatetheLocalAdminSIDtotheboundarydescriptor
//-->onlyapplicationsrunningunderanadministratoruser
//willbeabletoaccessthekernelobjectsinthesamenamespace

if(!AddSIDToBoundaryDescriptor(&g_hBoundary,pLocalAdminSID))
{
AddText(TEXT("AddSIDToBoundaryDescriptorfailed:%u/r/n"),
GetLastError());
return;
}

//CreatethenamespaceforLocalAdministratorsonly
SECURITY_ATTRIBUTESsa;
sa.nLength=sizeof(sa);
sa.bInheritHandle=FALSE;
if(!ConvertStringSecurityDescriptorToSecurityDescriptor(
TEXT("D:(A;;GA;;;BA)"),

SDDL_REVISION_1,&sa.lpSecurityDescriptor,NULL))
{
AddText(TEXT("SecurityDescriptorcreationfailed:%u/r/n"),GetLastError());
return;
}

g_hNamespace=
CreatePrivateNamespace(&sa,g_hBoundary,g_szNamespace);

//Don'tforgettoreleasememoryforthesecuritydescriptor
LocalFree(sa.lpSecurityDescriptor);


//Checktheprivatenamespacecreationresult
DWORDdwLastError=GetLastError();
if(g_hNamespace==NULL)


{
//Nothingtodoifaccessisdenied
//-->thiscodemustrununderaLocalAdministratoraccount
if(dwLastError==ERROR_ACCESS_DENIED)


{
AddText(TEXT("Accessdeniedwhencreatingthenamespace./r/n"));
AddText(TEXT("YoumustberunningasAdministrator./r/n/r/n"));
return;
}
else


{
if(dwLastError==ERROR_ALREADY_EXISTS)


{
//Ifanotherinstancehasalreadycreatedthenamespace,
//weneedtoopenitinstead.
AddText(TEXT("CreatePrivateNamespacefailed:%u/r/n"),dwLastError);
g_hNamespace=OpenPrivateNamespace(g_hBoundary,g_szNamespace);
if(g_hNamespace==NULL)


{
AddText(TEXT("andOpenPrivateNamespacefailed:%u/r/n"),
dwLastError);
return;
}
else


{
g_bNamespaceOpened=TRUE;
AddText(TEXT("butOpenPrivateNamespacesucceeded/r/n/r/n"));
}
}
else


{
AddText(TEXT("Unexpectederroroccured:%u/r/n/r/n"),dwLastError);
return;
}
}
}

//Trytocreatethemutexobjectwithaname
//basedontheprivatenamespace
TCHARszMutexName[64];
StringCchPrintf(szMutexName,_countof(szMutexName),TEXT("%s//%s"),g_szNamespace,TEXT("Singleton"));

g_hSingleton=CreateMutex(NULL,FALSE,szMutexName);//创建互斥量
if(GetLastError()==ERROR_ALREADY_EXISTS)


{
//ThereisalreadyaninstanceofthisSingletonobject
AddText(TEXT("AnotherinstanceofSingletonisrunning:/r/n"));
AddText(TEXT("-->Impossibletoaccessapplicationfeatures./r/n"));
}
else


{
//FirsttimetheSingletonobjectiscreated
AddText(TEXT("FirstinstanceofSingleton:/r/n"));
AddText(TEXT("-->Accessapplicationfeaturesnow./r/n"));
}
}


void
AddText(PCTSTRpszFormat,
)
{

va_listargList;
va_start(argList,pszFormat);

TCHARsz[20*1024];

Edit_GetText(DETAILS_CTRL,sz,_countof(sz));
_vstprintf_s(
_tcschr(sz,TEXT('/0')),_countof(sz)-_tcslen(sz),
pszFormat,argList);
Edit_SetText(DETAILS_CTRL,sz);
va_end(argList);
}