场景
explorer.exe
文件资源管理器中的文件拖向目标应用程序窗口时,如果目标窗口进程 MIC
权限级别高于 explorer.exe
,则会导致文件拖放失败,只有当目标窗口进程的 MIC
级别不大于 explorer.exe
进程的 MIC
级别才能正常拖放文件;而通常 explorer.exe
进程开机默认为中级MIC
,管理员权限运行的应用程序为高级MIC
。
解决
#define MSGFLT_ADD 1
#define MSGFLT_REMOVE 2
#define WM_COPYGLOBALDATA 0x049
#define WM_DROPFILES 0x0233
typedef BOOL (WINAPI *PFN_ChangeWindowMessageFilter)(UINT uMessage, int nFlag);
BOOL WINAPI ChangeWndMessageFilterOk(UINT nMessage, BOOL bAllow)
{
HMODULE hModUser32 = NULL;
hModUser32 = LoadLibrary(_T("user32.dll"));
if (hModUser32 == NULL)
{
return FALSE;
}
PFN_ChangeWindowMessageFilter pfnChangeWindowMessageFilter = (PFN_ChangeWindowMessageFilter)GetProcAddress(hModUser32, "ChangeWindowMessageFilter");
if (pfnChangeWindowMessageFilter == NULL)
{
FreeLibrary(hModUser32);
return FALSE;
}
FreeLibrary(hModUser32);
return pfnChangeWindowMessageFilter(nMessage, bAllow ? MSGFLT_ADD : MSGFLT_REMOVE);
}
使用:
ChangeWndMessageFilterOk(WM_DROPFILES, TRUE);
ChangeWndMessageFilterOk(WM_COPYGLOBALDATA, TRUE);
说明(MIC & UIPI)
Message Integrity Check
消息完整性检查(Message Integrity Check)是 Windows 7 增加的 Windows 安全对象访问控制安全机制,系统利用完整性级别对一个安全对象进行标记,通过降低进程的完整性级别可以限制其对安全对象的写入权限,这一点类似于用户帐户组的成员被限制访问系统组件这种方式。完整性检查机制使得用更少的权限或以更低的完整性级别运行一些程序,会降低进程修改系统或损害用户数据文件的可能性。在 Windows 7 中消息完整性检查分为 6 个等级,如下表所示:
MIC等级 | 说明 |
---|---|
SECURITY_MANDATORY_UNTRUSTED_RID | 不信任的MIC等级 |
SECURITY_MANDATORY_LOW_RID | 低MIC等级,如IE |
SECURITY_MANDATORY_MEDIUM_RID | 中MIC等级,默认为这个等级,如Explorer |
SECURITY_MANDATORY_HIGH_RID | 高MIC等级,以管理员身份运行的程序 |
SECURITY_MANDATORY_SYSTEM_RID | 系统MIC等级,一般是服务应用程序 |
SECURITY_MANDATORY_PROTECTED_PROCESS_RID | 被保护进程的MIC等级 |
User Interface Privilege Isolation
用户界面特权隔离(User Interface Privilege Isolation
),则是 Windows 7 通过 MIC 机制新引入的一种安全特性,用于拦截接收比自身进程 MIC 等级低的进程发来的消息。UIPI 的目的是为了规范不同进程窗口之间的窗口消息处理过程,默认情况下,高权限进程不会接收到低权限进程发送的窗口消息的,但是低权限进程能够接收到高权限进程的窗口消息。UIPI 的本质是系统检查目标窗口和发送方是否具有相同的 MIC 等级或者发送方具有更高的 MIC 等级,如果符合上述条件,则允许消息的传递,否则将消息丢弃。
因此,在 Windows 7 及以上操作系统中运行的用户进程,如果运行时具有不同的完整性等级,即具有不同的 MIC 等级,那么相互间的通信将会无法像 Windows XP 那样正常进行。