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

安全基础
正常关机后光电鼠标仍发光怎么解决
金山安全反病毒专家教你认识和安装系统补丁
微软IE团队成员揭秘中国网银不兼容非IE浏览器的原因
防火墙端口扫描和路径追踪设置防黑客入侵
压缩包里的压缩文件加上缩略图的方法
拒绝修改exe文件关联随EXE程序启动的木马
保护硬盘隐私数据防止黑客窃取的操作小方法
开机按F1故障怎么解决(新手学电脑)
实用技巧:自定义软件安装的默认路径
快速打开控制面板中的某一项目
避免网购被骗 揭秘网络钓鱼的9种骗术
删不掉文件的原因和辅助删除的软件工具
隐藏的系统克隆帐户全了解
剖析DDOS攻击的原理 提供解决方法
360安全卫士完美帮你系统打补丁
桌面多出几个IE图标有的不能删除怎么办
加载*dll出错,系统找不到指定的模块
如何揪出并根除Windows系统启动项
菜鸟防止黑客攻击的10个系统设置方法
新手学电脑:宽带拨号的设置方法

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-28   浏览: 38 ::
收藏到网摘: 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 检测的问题被分为两个部分:如何遍历调用堆栈;如何检测某个组件是否拥有权限。