微博|关于那些没有标准答案的问题一览

微博|关于那些没有标准答案的问题一览

有时候 , 有一些问题没有一个标准的答案 , 或者 , 即使它有答案 , 但是这个答案也是没有实际意义的 。 今天我们就来列举几个来看看 。
问题:我怎么知道当前系统里有多少个指向一个共享内存对象的引用?即使有办法知道 , 当你得到答案之后的几毫秒 , 你的答案已经是错误的了 。 为什么?因为有人可能在你获取引用数之后立即打开了一个新的引用句柄 。 这就是”由于无法避免的竞争条件所导致的无意义答案”的一个例子 。
问题:在不进入一个临界区的前提下 , 我如何确定这个临界区是未锁定的?和上面一样 , 当你得到答案后 , 可能立即会有另一个线程决定进入该临界区 , 从而让你刚刚得到的答案变成了错误的答案 。
问题:我如何确定当前系统上是否安装有一个键盘钩子?和上面一样 , 当你得到”肯定没有 , 一切安全”的答案后 , 可能会有人立即安装一个钩子 。
这个问题实际上会更严重 , 因为一般对这个问题感兴趣的人 , 通常会想要实现一个安全的键盘访问功能 。 但是这个时候 , 可能有人已经安装了一个键盘钩子 , 这就意味着 , 他们已经将代码挂接到你的进程中了(毕竟它是一个钩子嘛) 。 他们很容易将IsKeyboardHooked给Hook掉 , 并让其直接返回FALSE 。
现在当你的程序询问系统 , 当前是否有安装键盘钩子 , 在上面的情况下 , 你会直接得到一个”愉快的”答案:”没有 , 一切安全” 。 接下里你会”盲目自信”地相信这个答案 , 并认为系统里没有安装键盘钩子 。 这实际上是不可信的 , 只是因为这个是某个人Hook掉真实代码后伪造的一个假答案 。
你无法从系统本身内部可靠地推断该系统的安全性这就像是试图向自己证明我没有疯一样 。
系统本身可能已经受到攻击 , 因此你的所有推理都可以被虚拟化 。 此外 , 你的程序可能在虚拟机环境中运行 , 在这种情况下 , 虚拟机中缺少键盘钩子并不能证明什么 。 键盘记录可能发生在虚拟机的宿主软件中 。
从用户界面的角度来说 , 桌面是一个安全边界 。 一旦你让某人在你的桌面上运行 , 这就意味着你信任他们 。因为现在他们可以向你的程序发送随机消息、注入钩子、攻击你的窗口句柄、编辑你的菜单 , 并且通常还会在各种应用程序进程中晃来晃去 , 图谋不轨 。
这就是为什么让Windows服务与桌面交互是一个如此可怕的错误 。 通过允许和桌面交互 , 你就开始信任那些不应该信任的安全上下文了 。当然 , 它可以让你的Windows服务操控该桌面上的对象 , 但同时 , 它也可以让该桌面上的对象操控你的服务 。 这是一把双刃剑 , 在亲自行动之前 , 最好弄清楚其中的利害关系 。
总结安全问题无小事 , 切不可高估人性 。
这又使我想起了目前正在开发的拓扑梅尔智慧办公平台(Topomel Box) , 我在其中引入了契约式编程的理念 , 对于一个组件 , 它不应该相信任何从外部输入的数据 , 它应该怀疑一切 , 并对数据进行有效性校验 , 只有通过了检验才开始它的进一步动作 , 也即:所有组件之间都暗含一个个确定的契约 , 只有满足了契约所订立的约束 , 才会得到相应的服务 。
尼采:如果你长时间凝视深渊 , 深渊也在凝视你 。
最后Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一 , 里面有很多关于Windows的小知识 , 对于广大Windows平台开发者来说 , 确实十分有帮助 。