当前位置: 首页 > 图文教程 > 网络安全 > 安全基础 > CLR 中代码访问安全检测实现原理(2)

安全基础
IE浏览器防黑十大秘籍,黑客也没招
网络工程师讲解系统安全漏洞的形成和防治
清除导致XP系统反复重启的新网银木马
识破QQ欺骗网络地址的几种方法汇总
安全基础知识 细说暴库的原理与方法
排除无线突然中断故障实例
强搜天线 搜出WiFi世界的安全漏洞
网管应用技巧 内网安全十大策略说明
如何修改局域网内部打印机的IP地址
如何找出IIS中隐藏的网站
EFS加密技术的概念分析及一次解密经过
提高Windows XP系统安全性要关闭的10种服务
PHPBB 2.0.22 MOD版最新注入漏洞
修复Windows系统忘记密码的9个高招
用SockOnline软件轻松突破端口限制
安全基础知识 最强0到33600端口详解
执行文件方式加密FLASH文件的解密方法
网吧被入侵后的应对解决方法
网页“黑手”如何攻击你的Windows系统
不要让别人读了你的信 谈私密数据保护

安全基础 中的 CLR 中代码访问安全检测实现原理(2)


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-28   浏览: 35 ::
收藏到网摘: n/a

  虽然权限种类众多,但各种子类只负责定义自身权限的特性以及如何对自身权限验证,而所有的调用链遍历和验证工作,都是由 CodeAccessPermission.Demand() 方法完成的:

以下内容为程序代码:

public void CodeAccessPermission.Demand()
{
  CodeAccessSecurityEngine engine = SecurityManager.GetCodeAccessSecurityEngine();

  if ((engine != null) && !this.IsSubsetOf(null))
  {
    StackCrawlMark mark = StackCrawlMark.LookForMyCallersCaller;
    engine.Check(this, ref mark);
  }
}

  可以看到 CodeAccessPermission.Demand 方法,实际上是将验证操作转发给安全管理器 SecurityManager 的代码访问安全引擎 CodeAccessSecurityEngine 类型的 Check 方法完成的。

以下内容为程序代码:

internal class CodeAccessSecurityEngine
{
 internal virtual void Check(CodeAccessPermission cap, ref StackCrawlMark stackMark)
 {
  if (!PreCheck(cap, null, 1, ref stackMark, PermissionType.DefaultFlag))
  {
   Check(PermissionToken.GetToken(cap), cap, ref stackMark, -1, ((cap is IUnrestrictedPermission) ? 1 : 0));
  }
 }

 internal virtual void Check(CodeAccessPermission cap, ref StackCrawlMark stackMark, PermissionType permType)
 {
  int num1 = 0;
  if (CodeAccessSecurityEngine.GetResult(permType, out num1))
  {
   return;
  }
  if (this.PreCheck(cap, null, 1, ref stackMark, permType))
  {
   CodeAccessSecurityEngine.SetResult(permType, num1);
   return;
  }
  this.Check(PermissionToken.GetToken(cap), cap, ref stackMark, -1, ((cap is IUnrestrictedPermission) ? 1 : 0));
 }

 [MethodImpl(MethodImplOptions.InternalCall)]
 private void Check(PermissionToken permToken, CodeAccessPermission demand, ref StackCrawlMark stackMark, int checkFrames, int unrestrictedOverride);
}


  CodeAccessSecurityEngine 内部类的 Check 方法,将最终调用通过 Unmanaged 代码实现的内部方法进行安全检测。rotor 中的 COMCodeAccessSecurityEngine 类型 (ComCodeAccessSecurityEngine.cpp) 实现了这个检测逻辑。
  COMCodeAccessSecurityEngine::Check 函数 (ComCodeAccessSecurityEngine.cpp:683) 通过调用 COMCodeAccessSecurityEngine::CheckInternal 函数 (ComCodeAccessSecurityEngine.cpp:697) 填充一个堆栈遍历请求结构 CasCheckWalkData 的内容,最终将请求转发给 StandardCodeAccessCheck 函数 (ComCodeAccessSecurityEngine.cpp:563) 完成检测。此结构的指针将作为堆栈遍历回调函数的参数传递给回调函数进行实际权限验证,而 StandardCodeAccessCheck 只是负责调用全局堆栈遍历支持 StackWalkFunctions 函数(StackWalk.cpp:512),以 CodeAccessCheckStackWalkCB 函数 (ComCodeAccessSecurityEngine.cpp:449) 为回调函数,以 CheckInternal 函数填充的 CasCheckWalkData 结构为参数,通过现成的堆栈遍历支持 Thread::StackWalkFrames 完成堆栈遍历。

  通过堆栈遍历实现代码访问安全检测调用流程如下:

以下为引用:

CodeAccessSecurityEngine::Check 内部调用定义,由下面的函数实现
 COMCodeAccessSecurityEngine::Check 转发检测请求 (ComCodeAccessSecurityEngine.cpp:683)
  COMCodeAccessSecurityEngine::CheckInternal 填充 CasCheckWalkData 结构 (ComCodeAccessSecurityEngine.cpp:697)
   StandardCodeAccessCheck 执行堆栈遍历
    Thread::StackWalkFrames 遍历当前线程堆栈
     CodeAccessCheckStackWalkCB 检测当前组件权限 (ComCodeAccessSecurityEngine.cpp:449)


  因此现在 CAS 检测的问题被分为两个部分:如何遍历调用堆栈;如何检测某个组件是否拥有权限。