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

安全基础
如何确保应用系统的安全
不再怕攻击 拨号上网必学的几招安全技巧
用微软工具MBSA了解电脑的“安全红线”
WinXP/2K鲜为人知的安全命令
用ISA+瑞星构筑防范黑客和病毒攻击的铜墙铁壁
思科警告用户注意IOS漏洞
Winzip存在多个缓冲区溢出漏洞
网络管理员必读之如何让DHCP服务器更安全
防范网页木马的攻击
Linux又出现高危险图像漏洞 厂商急于打补丁
三招两式保护Windows系统不受恶意代码攻击
三种对付恶意网站的绝招
绿盟评出2004年09月十大网络安全漏洞
Norton Internet Security 2005全面保护系统安全
解决IE强迫连接某网站的办法
浅析传统网络防火墙的五大不足之处
防范非法用户入侵Win 2000/XP系统七招
Microsoft 发布5个新的安全补丁
浅析三种不同的“防Ping”方法
Microsoft AntiSpyware微软出品的反间谍软件

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-28   浏览: 75 ::
收藏到网摘: 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 检测。