面对IE保护模式的开发者生存之道
当我们只把对象名传递给EXE的时候如果我们使用以上步骤,我们将产生一个竞态条件,在这个EXE程序有机会打开其上的一个句柄前,这个插件可能会关闭它的句柄(因此会删除这个IPC对象),过程如下:
1、该插件创建IPC对象,将其引用计数设为1。
2、插件起动新进程,将IPC对象的名字传递给它。引用计数依然是1。
3、插件不能立即关闭它的句柄,它需要等到新进程打开一个到对象的句柄。要实现这个任务需要某些类别的同步。
4、新的进程打开一个到对象的句柄,然后读取数据。这个时候,它可以发信号给插件以唤醒插件线程。现在插件可以安全的关闭它的句柄了。
在示例项目中我选择的做法是,在DemoApp创建主对话框前,让它从共享内存中读数据。插件在CreateProcess()后调用WaitForInputIdle(),这将使该线程被阻挡,直到DemoApp的主对话框已经被创建和显示。一旦DemoApp的线程空闲后,它已经结束了对共享内存的使用,对插件来说,关闭它的句柄已经安全。
band演示了通过共享内存传递数据的两种方法。当你点击Run EXE 1按钮的时候,band写当前的日期和时间到共享内存中,然后传递一个句柄给DemoApp。当保护模式被启用的时候,这个方法将失败,DemoApp将报告非法的句柄错误。点击Run EXE 2按钮,传递文件映射对象的名称给DemoApp,它将显示它从共享内存中读取的数据:

2.接收Windows消息
UIPI阻止特定的windows消息被从一个低完整性级别进程发送到一个高完整性级别进程。如果你的应用程序需要接收来自你的插件的消息,你可以调用ChangeWindowMessageFilter()来允许一个特定的消息通过:
BOOL ChangeWindowMessageFilter(UINT message, DWORD dwFlag);参数message是消息的值,而dwFlag则指明这个消息是被允许还是阻挡。传递MSGFLT_ADD则是允许消息传递,而MSGFLT_REMOVE则是阻挡它。当处理来自其他进程的windows消息时一定要非常小心——如果通过消息来接收数据,你必须将它看作非信任的,你应该在根据它行动前对它进行验证确认。(Remember that inter-process messages can be sent from anywhere, and such messages can be used for attacks, as mentioned earlier.)
本文中的演示项目显示了如何通过registered windows消息进行通信。对于mutex示例,有两个消息。DemoApp通过OnInitDialog()中的代码允许第二个消息通过过滤器:
m_uRegisteredMsg1 = RegisterWindowMessage( REGISTERED_MSG1_NAME );当你点击band中的两个Send Message按钮后,你将看到如下结果:
m_uRegisteredMsg2 = RegisterWindowMessage( REGISTERED_MSG2_NAME );
ChangeWindowMessageFilter( m_uRegisteredMsg2, MSGFLT_ADD );

第一个消息没有被允许通过过滤器,SendMessage()返回了0。
0
相关文章