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

安全基础
网络协议分析软件的编写
一个SYN攻击的源程序
彻底清查带毒的Cookie
解析cookie欺骗实现过程及具体应用
从芯认识 浅谈宽带路由器处理芯片
搜索引擎也另类 想搜啥就搜啥
命令提示符恢复本地安全策略小技巧
根据PID查杀木马病毒的适用小方法
网络管理员日志之硬件修理篇
著名黑客Kevin Mitnick谈网络安全
Windows XP 常见的进程列表
网络攻击概览
爱机中毒自救六招
引起网络广播风暴的几种原因
黑客入侵36计
局域网测试及故障排除经验谈
不可忽视的BIOS参数设置
微软IE浏览器非常规修改全攻略(上)
微软IE浏览器非常规修改全攻略(下)
网管十招

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


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

  首先来看看 Security::SecWalkCommonProlog 函数 (Security.cpp:406) 定义的特殊帧。首先会跳过遍历操作的调用者自己的帧;然后当进行堆栈遍历指定最大帧数为1时,跳过所有 Reflection/Remoting 调用的内部帧;最后针对 LookForMyCallersCaller 这种特殊调用,以及指定最大帧数进行处理。

以下内容为程序代码:

BOOL Security::SecWalkCommonProlog (SecWalkPrologData * pData, MethodDesc * pMeth, StackWalkAction * pAction, CrawlFrame * pCf)
{
 *pAction = SWA_CONTINUE;

 // 跳过 CAS 检测调用帧
 if ((pData->pStackMark != NULL) && !IsInCalleesFrames(pCf->GetRegisterSet(), pData->pStackMark))
  return TRUE;


 // 跳过内部函数帧,如 Reflection / Remoting 调用的内部帧等等
 if (pData->dwFlags & CORSEC_SKIP_INTERNAL_FRAMES)
 {
  // 跳过 Remoting.Messaging.StackBuilderSink.PrivateProcessMessage 方法
  if (pMeth == s_stdData.pMethPrivateProcessMessage)
  {
   pData->bSkippingRemoting = TRUE;
   return TRUE
  }

  // 跳过 Remoting 透明代理帧
  if (!pCf->IsFrameless() && pCf->GetFrame()->GetFrameType() == Frame::TYPE_TP_METHOD_FRAME)
  {
   pData->bSkippingRemoting = FALSE;
   return TRUE;
  }

  // 跳过 Remoting 帧
  if (pData->bSkippingRemoting)
   return TRUE;

  // 跳过 Refection 相关类型的方法帧
  MethodTable *pMT = pMeth->GetMethodTable();

  if (pMT == s_stdData.pTypeRuntimeMethodInfo ||
    pMT == s_stdData.pTypeMethodBase ||
    pMT == s_stdData.pTypeRuntimeConstructorInfo ||
    pMT == s_stdData.pTypeConstructorInfo ||
    pMT == s_stdData.pTypeRuntimeType ||
    pMT == s_stdData.pTypeType ||
    pMT == s_stdData.pTypeRuntimeEventInfo ||
    pMT == s_stdData.pTypeEventInfo ||
    pMT == s_stdData.pTypeRuntimePropertyInfo ||
    pMT == s_stdData.pTypePropertyInfo ||
    pMT == s_stdData.pTypeActivator ||
    pMT == s_stdData.pTypeAppDomain ||
    pMT == s_stdData.pTypeAssembly)
  {
   return TRUE;
  }
 }

 // 如果只希望检测调用者的调用者两级,则跳过其他的所有帧
 if ((pData->pStackMark != NULL) && (*pData->pStackMark == LookForMyCallersCaller) && !pData->bFoundCaller)
 {
  pData->bFoundCaller = TRUE;
  return TRUE;
 }

 // 最多只检测 cCheck 帧
 if (pData->cCheck >= 0)
 {
  if (pData->cCheck == 0)
  {
   pData->dwFlags |= CORSEC_STACKWALK_HALTED;
   *pAction = SWA_ABORT;
   return TRUE;
  }
  else
  {
   --(pData->cCheck);
  }
 }

 return FALSE;
}


  在跳过了这些无需处理的堆栈帧后,CodeAccessCheckStackWalkCB 函数将对 Assembly/AppDomain 变化,和显式指定安全对象的情况,进行 CAS 检测。