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


{//检查实例
// Create the boundary descriptor
g_hBoundary = CreateBoundaryDescriptor(g_szBoundary, 0);

// Create a SID corresponding to the Local Administrator group
BYTE localAdminSID[SECURITY_MAX_SID_SIZE];
PSID pLocalAdminSID = &localAdminSID;
DWORD cbSID = sizeof(localAdminSID);
if (!CreateWellKnownSid(
WinBuiltinAdministratorsSid, NULL, pLocalAdminSID, &cbSID)

)
{
AddText(TEXT("AddSIDToBoundaryDescriptor failed: %u\r\n"),
GetLastError());
return;
}
// Associate the Local Admin SID to the boundary descriptor
// --> only applications running under an administrator user
// will be able to access the kernel objects in the same namespace

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

// Create the namespace for Local Administrators only
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.bInheritHandle = FALSE;
if (!ConvertStringSecurityDescriptorToSecurityDescriptor(
TEXT("D:(A;;GA;;;BA)"),

SDDL_REVISION_1, &sa.lpSecurityDescriptor, NULL))
{
AddText(TEXT("Security Descriptor creation failed: %u\r\n"), GetLastError());
return;
}

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

// Don't forget to release memory for the security descriptor
LocalFree(sa.lpSecurityDescriptor);


// Check the private namespace creation result
DWORD dwLastError = GetLastError();
if (g_hNamespace == NULL)

{
// Nothing to do if access is denied
// --> this code must run under a Local Administrator account
if (dwLastError == ERROR_ACCESS_DENIED)

{
AddText(TEXT("Access denied when creating the namespace.\r\n"));
AddText(TEXT(" You must be running as Administrator.\r\n\r\n"));
return;
}
else

{
if (dwLastError == ERROR_ALREADY_EXISTS)

{
// If another instance has already created the namespace,
// we need to open it instead.
AddText(TEXT("CreatePrivateNamespace failed: %u\r\n"), dwLastError);
g_hNamespace = OpenPrivateNamespace(g_hBoundary, g_szNamespace);
if (g_hNamespace == NULL)

{
AddText(TEXT(" and OpenPrivateNamespace failed: %u\r\n"),
dwLastError);
return;
}
else

{
g_bNamespaceOpened = TRUE;
AddText(TEXT(" but OpenPrivateNamespace succeeded\r\n\r\n"));
}
}
else

{
AddText(TEXT("Unexpected error occured: %u\r\n\r\n"),dwLastError);
return;
}
}
}
// Try to create the mutex object with a name
// based on the private namespace
TCHAR szMutexName[64];
StringCchPrintf(szMutexName, _countof(szMutexName), TEXT("%s\\%s"), g_szNamespace, TEXT("Singleton"));

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

{
// There is already an instance of this Singleton object
AddText(TEXT("Another instance of Singleton is running:\r\n"));
AddText(TEXT("--> Impossible to access application features.\r\n"));
}
else

{
// First time the Singleton object is created
AddText(TEXT("First instance of Singleton:\r\n"));
AddText(TEXT("--> Access application features now.\r\n"));
}
}




void AddText(PCTSTR pszFormat,
)
{

va_list argList;
va_start(argList, pszFormat);

TCHAR sz[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);
}

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述
2007-06-08 OnDraw()和OnPaint()的区别
2006-06-08 《Java编程思想》读书笔记(11)
2006-06-08 TOJ_1002解题报告
2006-06-08 TOJ_1001解题报告
2006-06-08 《Java编程思想》读书笔记(10)