<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>kernsec</title>
    <link>https://wechat2rss.xlab.app/feed/4767e1bec36c42a1c1cf1c991a3a1a027d1b49a5.xml</link>
    <description>内核安全NBXL&#xA;(wechat feed made by @ttttmr https://wechat2rss.xlab.app)</description>
    <managingEditor> (kernsec)</managingEditor>
    <image>
      <url>https://wx.qlogo.cn/mmhead/Q3auHgzwzM4EibxDfjyV4xhicX0u8SGvI0KdajeBAKBwcdMqBj7Ful4A/0</url>
      <title>kernsec</title>
      <link>https://wechat2rss.xlab.app/feed/4767e1bec36c42a1c1cf1c991a3a1a027d1b49a5.xml</link>
    </image>
    <item>
      <title>IOS 代码签名深度分析</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg4NjU1NDU4MA==&amp;mid=2247483872&amp;idx=1&amp;sn=167c757186931b3f09d7993c9d5d8677</link>
      <description>OS的代码签名机制是套复杂的系统工程，本文从用户态工具到内核态处理流程对ios代码签名机制做深度分析</description>
      <content:encoded><![CDATA[<p>原创 <span>wzt</span> <span>2026-01-03 08:34</span> <span style="display: inline-block;">浙江</span></p>






  
  <p><img src="https://wechat2rss.xlab.app/img-proxy/?k=68f90062&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_jpg%2F4iaJia7Cvd3PCcaUQAPnA3CiaWIoY75XnkMeLA29k7umC58REgGibo12epJhic1lKDrHc5d63RGfQIXUdpIQaZSZFvg%2F0%3Fwx_fmt%3Djpeg"/></p>
  <p>OS的代码签名机制是套复杂的系统工程，本文从用户态工具到内核态处理流程对ios代码签名机制做深度分析</p>
  <p><span leaf=""><span textstyle="" style="font-size: 24px;font-weight: bold;">1 简介</span></span></p><p style=""><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">    IOS</span></span><span lang="ZH" style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">的代码签名机制是套复杂的系统工程，</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">本文从用户态工具到内核态处理流程对</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">ios</span></span><span lang="ZH" style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">代码签名机制做一个完全的分析。</span></span></p><h1><span style="mso-bookmark:_Toc22159;"><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:
ZH;"><span leaf=""><span textstyle="" style="font-size: 24px;font-weight: bold;">2 用户态工具</span></span></span></span></h1><p style=""><span lang="ZH" style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">  苹果公司的</span></span><span lang="EN-US" style="mso-fareast-language:
ZH;"><span leaf="">objectc</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:
ZH;"><span leaf="">和</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">swift</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">语言经过编译后的二进制文件为</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">mach-o</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;mso-fareast-language:ZH;"><span leaf="">格式，这是苹果公司自己设计的一个二进制文件格式，通过</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">xcode</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;mso-fareast-language:ZH;"><span leaf="">的签名工具将签名信息保存在</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">macho</span></span><span lang="ZH" style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">文件的一个特定</span></span><span lang="EN-US" style="mso-fareast-language:
ZH;"><span leaf="">section</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:
ZH;"><span leaf="">：</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">LC_CODE_SIGNATURE</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">。</span></span></p><p style=""><span lang="ZH" style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">  苹果公司对</span></span><span lang="EN-US" style="mso-fareast-language:
ZH;"><span leaf="">macho</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:
ZH;"><span leaf="">的签名包含两种信息，第一个信息是文件的</span></span><span lang="EN-US" style="mso-fareast-language:
ZH;"><span leaf="">hash</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:
ZH;"><span leaf="">，以页为单位算出</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">hash</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">值，将所有的</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">hash</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;mso-fareast-language:ZH;"><span leaf="">值保存在上述</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">section</span></span><span lang="ZH" style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">里。另一个信息是由苹果公司签发的证书信息。证书用来证明</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">app</span></span><span lang="ZH" style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">的来源可靠，</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">hash</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">值用来检测每次</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">app</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;mso-fareast-language:ZH;"><span leaf="">启动时的完整性，确保不被篡改。</span></span></p><h2><span style="mso-bookmark:_Toc23481;"><span lang="ZH" style="font-family:黑体;mso-ascii-font-family:
Arial;mso-hansi-font-family:Arial;mso-fareast-language:ZH;"><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">2.1 签名信息的格式</span></span></span></span></h2><p style=""><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">    xcode</span></span><span lang="ZH" style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">调用</span></span><span lang="EN-US" style="mso-fareast-language:
ZH;"><span leaf="">codesign</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:
ZH;"><span leaf="">用户态工具，对</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">app</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">进行签名，签名信息被</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">llvm</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;mso-fareast-language:ZH;"><span leaf="">编译器链接进</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">macho</span></span><span lang="ZH" style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">里，它被表示成一个数据结构为：</span></span></p><p><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">osfmk/kern/cs_blobs.h</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf=""><span class="code-snippet__keyword">typedef</span> <span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">__CodeDirectory</span> {</span></code><br/><code><span leaf=""> <span class="code-snippet__type">uint32_t</span> magic;                                 <span class="code-snippet__comment">/* magic number (CSMAGIC_CODEDIRECTORY) */</span></span></code><br/><code><span leaf=""> <span class="code-snippet__type">uint32_t</span> length;                                <span class="code-snippet__comment">/* total length of CodeDirectory blob */</span></span></code><br/><code><span leaf=""> <span class="code-snippet__type">uint32_t</span> version;                               <span class="code-snippet__comment">/* compatibility version */</span></span></code><br/><code><span leaf=""> <span class="code-snippet__type">uint32_t</span> flags;                                 <span class="code-snippet__comment">/* setup and mode flags */</span></span></code><br/><code><span leaf=""> <span class="code-snippet__type">uint32_t</span> hashOffset;                    <span class="code-snippet__comment">/* offset of hash slot element at index zero */</span></span></code><br/><code><span leaf=""> <span class="code-snippet__type">uint32_t</span> identOffset;                   <span class="code-snippet__comment">/* offset of identifier string */</span></span></code><br/><code><span leaf=""> <span class="code-snippet__type">uint32_t</span> nSpecialSlots;                 <span class="code-snippet__comment">/* number of special hash slots */</span></span></code><br/><code><span leaf=""> <span class="code-snippet__type">uint32_t</span> nCodeSlots;                    <span class="code-snippet__comment">/* number of ordinary (code) hash slots */</span></span></code><br/><code><span leaf=""> <span class="code-snippet__type">uint32_t</span> codeLimit;                             <span class="code-snippet__comment">/* limit to main image signature range */</span></span></code><br/><code><span leaf=""> <span class="code-snippet__type">uint8_t</span> hashSize;                               <span class="code-snippet__comment">/* size of each hash in bytes */</span></span></code><br/><code><span leaf="">...</span></code><br/><code><span leaf=""> <span class="code-snippet__type">uint8_t</span> hashType;</span></code><br/><code><span leaf="">} CS_CodeDirectory</span></code><br/><code><span leaf="">__attribute__ ((<span class="code-snippet__built_in">aligned</span>(<span class="code-snippet__number">1</span>)));</span></code><br/></pre></p><p><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">    其中</span></span><span lang="EN-US" style="mso-fareast-language:
ZH;"><span leaf="">hashOffset</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:
ZH;"><span leaf="">保存的就是文件以页为单位的所有</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">sha256 hash</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:
ZH;"><span leaf="">。</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">macos</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">系统没有自带的工具能识别出这些</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">hash</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;mso-fareast-language:ZH;"><span leaf="">，可以使用开源的</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">jtool2</span></span><span lang="ZH" style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">工具，本文使用笔者自己开发的一个工具</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">ikit</span></span><span lang="ZH" style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">工具来解析签名信息。</span></span></p><p><span lang="EN-US" style="mso-fareast-language:ZH;mso-no-proof:
yes;"><span leaf=""><img data-aistatus="1" alt="1" class="rich_pages wxw-img" data-ratio="0.45925925925925926" data-type="jpeg" data-w="1080" height="254" width="553" data-imgfileid="100000218" src="https://wechat2rss.xlab.app/img-proxy/?k=9d8ad8aa&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_jpg%2F4iaJia7Cvd3PCeibxXOIGLRw6XZ7fY9oXHBgiaf1E0wOuaiawMFczpzHeWUrDupOiaeSuVRmuRZHr7bRt8ybqID4erEw%2F640%3Fwx_fmt%3Djpeg%26from%3Dappmsg"/></span></span></p><p style=""><span lang="ZH" style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">  它可以分析</span></span><span lang="EN-US" style="mso-fareast-language:
ZH;"><span leaf="">ios</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:
ZH;"><span leaf="">的</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">kernelcache</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">，解析</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">device tree, </span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;mso-fareast-language:ZH;"><span leaf="">提取</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">kext</span></span><span lang="ZH" style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">，解析</span></span><span lang="EN-US" style="mso-fareast-language:
ZH;"><span leaf="">macho</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:
ZH;"><span leaf="">文件的</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">hash</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">信息、</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">entitlements</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;mso-fareast-language:ZH;"><span leaf="">以及</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">cms</span></span><span lang="ZH" style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">信息。</span></span></p><p style=""><span lang="ZH" style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">  使用</span></span><span lang="EN-US" style="mso-fareast-language:
ZH;"><span leaf="">--sig</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:
ZH;"><span leaf="">参数提取</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">safari</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">的所有</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">hash</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;mso-fareast-language:ZH;"><span leaf="">信息。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="swift"><code><span leaf=""><span class="code-snippet__operator">./</span>ikit <span class="code-snippet__operator">--</span>sig <span class="code-snippet__operator">-</span>v <span class="code-snippet__regexp">/Applications/</span><span class="code-snippet__type">Safari</span>.app<span class="code-snippet__regexp">/Contents/</span><span class="code-snippet__type">MacOS</span><span class="code-snippet__operator">/</span><span class="code-snippet__type">Safari</span> <span class="code-snippet__operator">&gt;</span>safari.hash</span></code></pre></p><p><span lang="EN-US" style="mso-fareast-language:ZH;mso-no-proof:
yes;"><span leaf=""><img data-aistatus="1" alt="1" class="rich_pages wxw-img" data-ratio="0.524074074074074" data-type="jpeg" data-w="1080" height="290" width="552" data-imgfileid="100000220" src="https://wechat2rss.xlab.app/img-proxy/?k=ba6fade0&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_jpg%2F4iaJia7Cvd3PCeibxXOIGLRw6XZ7fY9oXHBHjKVdCApE7Tq2cHqic4wfMkF69tw1q728rvibOnicnNhfloTRufG3GiaUA%2F640%3Fwx_fmt%3Djpeg%26from%3Dappmsg"/></span></span></p><p style=""><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">    CodeDirectory</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;mso-fareast-language:ZH;"><span leaf="">除了保存文件的</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">hash</span></span><span lang="ZH" style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">值以外，还会保存另外七个特殊类型的</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">hash</span></span><span lang="ZH" style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">：</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="ini"><code><span leaf=""><span class="code-snippet__attr">CSSLOT_CODEDIRECTORY</span> = <span class="code-snippet__number">0</span>,                               /* slot index for CodeDirectory */</span></code><br/><code><span leaf=""> <span class="code-snippet__attr">CSSLOT_INFOSLOT</span> = <span class="code-snippet__number">1</span>,</span></code><br/><code><span leaf=""> <span class="code-snippet__attr">CSSLOT_REQUIREMENTS</span> = <span class="code-snippet__number">2</span>,</span></code><br/><code><span leaf=""> <span class="code-snippet__attr">CSSLOT_RESOURCEDIR</span> = <span class="code-snippet__number">3</span>,</span></code><br/><code><span leaf=""> <span class="code-snippet__attr">CSSLOT_APPLICATION</span> = <span class="code-snippet__number">4</span>,</span></code><br/><code><span leaf=""> <span class="code-snippet__attr">CSSLOT_ENTITLEMENTS</span> = <span class="code-snippet__number">5</span>,</span></code><br/><code><span leaf=""> <span class="code-snippet__attr">CSSLOT_DER_ENTITLEMENTS</span> = <span class="code-snippet__number">7</span>,</span></code><br/></pre></p><p><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">    CSSLOT_DER_ENTITLEMENTS</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;mso-fareast-language:ZH;"><span leaf="">是苹果公司在新版</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">macos/ios</span></span><span lang="ZH" style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">中新加入的</span></span><span lang="EN-US" style="mso-fareast-language:
ZH;"><span leaf="">entitlements</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:
ZH;"><span leaf="">类型，用</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">DER</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">格式表示。</span></span></p><p><span lang="EN-US" style="mso-fareast-language:ZH;mso-no-proof:
yes;"><span leaf=""><img data-aistatus="1" alt="1" class="rich_pages wxw-img" data-ratio="0.19166666666666668" data-type="jpeg" data-w="1080" height="106" width="553" data-imgfileid="100000217" src="https://wechat2rss.xlab.app/img-proxy/?k=1af7dd1e&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_jpg%2F4iaJia7Cvd3PCeibxXOIGLRw6XZ7fY9oXHBoZbttjxc3ibhp8C53TdARFlib3wTCLeGDRzl1gMFhghL9nbH3ibRcVnibg%2F640%3Fwx_fmt%3Djpeg%26from%3Dappmsg"/></span></span></p><p style=""><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">    Entitlements</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;mso-fareast-language:ZH;"><span leaf="">是整个</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">xml</span></span><span lang="ZH" style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">信息的</span></span><span lang="EN-US" style="mso-fareast-language:
ZH;"><span leaf="">hash</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:
ZH;"><span leaf="">值，使用</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">ikit</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">的</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">--ent</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;mso-fareast-language:ZH;"><span leaf="">参数可以提取出所有的</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">entitlements</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;mso-fareast-language:ZH;"><span leaf="">列表。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="swift"><code><span leaf=""><span class="code-snippet__operator">./</span>ikit <span class="code-snippet__operator">--</span>ent <span class="code-snippet__operator">-</span>v <span class="code-snippet__regexp">/Applications/</span><span class="code-snippet__type">Safari</span>.app<span class="code-snippet__regexp">/Contents/</span><span class="code-snippet__type">MacOS</span><span class="code-snippet__operator">/</span><span class="code-snippet__type">Safari</span> <span class="code-snippet__operator">&gt;</span>safari.ent</span></code></pre></p><p><span lang="EN-US" style="mso-fareast-language:ZH;mso-no-proof:
yes;"><span leaf=""><img data-aistatus="1" alt="1" class="rich_pages wxw-img" data-ratio="0.6833333333333333" data-type="jpeg" data-w="1080" height="378" width="553" data-imgfileid="100000219" src="https://wechat2rss.xlab.app/img-proxy/?k=8fc5d890&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_jpg%2F4iaJia7Cvd3PCeibxXOIGLRw6XZ7fY9oXHBwuG6DERia5rYhibzGSGsl8dmg1KUC1cylx7uolAMaev07dibWNyl0siciaA%2F640%3Fwx_fmt%3Djpeg%26from%3Dappmsg"/></span></span></p><h1><span style="mso-bookmark:_Toc3354;"><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:
ZH;"><span leaf=""><span textstyle="" style="font-size: 24px;font-weight: bold;">3 内核态流程</span></span></span></span></h1><h2><span style="mso-bookmark:
_Toc25287;"><span style="font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:
Arial;"><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">3.1 简介</span></span></span></span></h2><p style=""><span lang="EN-US"><span leaf="">    IOS</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">的代码签名过程分为启动前、运行时、退出时。</span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf=""><span textstyle="" style="font-size: 18px;font-weight: bold;">3.1.1 进程启动前验签过程</span></span></span></p><p style=""><span lang="ZH" style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">签名的解析发生在</span></span><span lang="EN-US" style="mso-fareast-language:
ZH;"><span leaf="">macho</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:
ZH;"><span leaf="">从磁盘加载到内核的过程中。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf="">bsd/kern/mach_loader.<span class="code-snippet__function">c</span></span></code><br/><code><span leaf=""><span class="code-snippet__title">parse_machfile</span><span class="code-snippet__params">(</span></span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">struct</span> vnode            *vp,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_map_t</span>                map,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">thread_t</span>                thread,</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">struct</span> mach_header      *header,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">off_t</span>                   file_offset,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">off_t</span>                   macho_size,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">int</span>                     depth,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">int64_t</span>                 aslr_offset,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">int64_t</span>                 dyld_aslr_offset,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">load_result_t</span>           *result,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">load_result_t</span>           *binresult,</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">struct</span> image_params     *imgp</span></code><br/><code><span leaf=""> )</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (<span class="code-snippet__built_in">os_add_overflow</span>(mach_header_sz, header-&gt;sizeofcmds, &amp;cmds_size) ||</span></code><br/><code><span leaf="">    (<span class="code-snippet__type">off_t</span>)cmds_size &gt; macho_size ||</span></code><br/><code><span leaf="">    <span class="code-snippet__built_in">round_page_overflow</span>(cmds_size, &amp;alloc_size) ||</span></code><br/><code><span leaf="">    alloc_size &gt; INT_MAX) {</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">return</span> LOAD_BADMACHO;</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> addr = <span class="code-snippet__built_in">kalloc_data</span>(alloc_size, Z_WAITOK);</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (addr == <span class="code-snippet__literal">NULL</span>) {</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">return</span> LOAD_NOSPACE;</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> error = <span class="code-snippet__built_in">vn_rdwr</span>(UIO_READ, vp, addr, (<span class="code-snippet__type">int</span>)alloc_size, file_offset,</span></code><br/><code><span leaf="">    UIO_SYSSPACE, <span class="code-snippet__number">0</span>, <span class="code-snippet__built_in">vfs_context_ucred</span>(imgp-&gt;ip_vfs_context), &amp;resid, p);</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (error) {</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">kfree_data</span>(addr, alloc_size);</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">return</span> LOAD_IOERROR;</span></code><br/><code><span leaf=""> }</span></code><br/></pre></p><p><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">    请注意</span></span><span lang="EN-US" style="background:
red;mso-highlight:red;"><span leaf="">xnu</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;background:red;mso-highlight:red;"><span leaf="">一次性将</span></span><span lang="EN-US" style="background:red;mso-highlight:red;"><span leaf="">command</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;background:red;mso-highlight:red;"><span leaf="">全部从磁盘读入内存，</span></span><span lang="EN-US" style="background:red;mso-highlight:red;"><span leaf=""> text</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;background:red;mso-highlight:red;"><span leaf="">段等都包含在其内，这为后面校验</span></span><span lang="EN-US" style="background:
red;mso-highlight:red;"><span leaf="">hash</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;background:red;mso-highlight:red;"><span leaf="">提供了方便。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf="">...</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">case</span> LC_CODE_SIGNATURE:</span></code><br/><code><span leaf=""> ret = <span class="code-snippet__built_in">load_code_signature</span>(</span></code><br/><code><span leaf=""> (<span class="code-snippet__keyword">struct</span> linkedit_data_command *) lcp,</span></code><br/><code><span leaf=""> vp,</span></code><br/><code><span leaf=""> file_offset,</span></code><br/><code><span leaf=""> macho_size,</span></code><br/><code><span leaf=""> header-&gt;cputype,</span></code><br/><code><span leaf=""> header-&gt;cpusubtype,</span></code><br/><code><span leaf=""> result,</span></code><br/><code><span leaf=""> imgp);</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">while</span> (off &lt; alloc_size &amp;&amp; ret == LOAD_SUCCESS) {</span></code><br/><code><span leaf=""> tainted = CS_VALIDATE_TAINTED;</span></code><br/><code><span leaf=""> valid = <span class="code-snippet__built_in">cs_validate_range</span>(vp,</span></code><br/><code><span leaf=""> <span class="code-snippet__literal">NULL</span>,</span></code><br/><code><span leaf="">ile_offset + off,</span></code><br/><code><span leaf=""> (<span class="code-snippet__type">const</span> <span class="code-snippet__type">void</span> *)((<span class="code-snippet__type">uintptr_t</span>)addr + off),</span></code><br/><code><span leaf=""><span class="code-snippet__built_in">MIN</span>(PAGE_SIZE, cmds_size),</span></code><br/><code><span leaf="">&amp;tainted);</span></code><br/><code><span leaf="">}</span></code><br/><code><span leaf="">}</span></code><br/></pre></p><p><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">load_code_signature</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;mso-fareast-language:ZH;"><span leaf="">用来解析签名信息。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf=""><span class="code-snippet__function"><span class="code-snippet__type">static</span></span><span class="code-snippet__function"><span class="code-snippet__type">load_return_t</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__title">load_code_signature</span><span class="code-snippet__params">(</span></span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">struct</span> linkedit_data_command    *lcp,</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">struct</span> vnode                    *vp,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">off_t</span>                           macho_offset,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">off_t</span>                           macho_size,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">cpu_type_t</span>                      cputype,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">cpu_subtype_t</span>                   cpusubtype,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">load_result_t</span>                   *result,</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">struct</span> image_params             *imgp)</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""> blob = <span class="code-snippet__built_in">ubc_cs_blob_get</span>(vp, cputype, cpusubtype, macho_offset);</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (blob != <span class="code-snippet__literal">NULL</span>) {</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">return</span>;</span></code><br/><code><span leaf=""> }</span></code><br/></pre></p><p><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">    首先从文件</span></span><span lang="EN-US" style="mso-fareast-language:
ZH;"><span leaf="">vnode</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:
ZH;"><span leaf="">节点中提取出一个</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">struct cs_blob</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">结构，它保存的是签名信息，如果这个签名信息已经存在，则直接返回成功。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="nginx"><code><span leaf=""><span class="code-snippet__attribute">kr</span> = ubc_cs_blob_allocate(&amp;addr, &amp;blob_size);</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">if</span> (kr != KERN_SUCCESS) {</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">ret</span> = LOAD_NOSPACE;</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">goto</span> out;</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">resid</span> = <span class="code-snippet__number">0</span>;</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">error</span> = vn_rdwr(UIO_READ,</span></code><br/><code><span leaf="">vp,</span></code><br/><code><span leaf="">(caddr_t) addr,</span></code><br/><code><span leaf="">lcp-&gt;datasize,</span></code><br/><code><span leaf="">macho_offset + lcp-&gt;dataoff,</span></code><br/><code><span leaf="">UIO_SYSSPACE,</span></code><br/><code><span leaf=""><span class="code-snippet__number">0</span>,</span></code><br/><code><span leaf="">kauth_cred_get(),</span></code><br/><code><span leaf="">&amp;resid,</span></code><br/><code><span leaf="">current_proc());</span></code><br/></pre></p><p style=""><span lang="ZH" style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">  如果不存在则调用</span></span><span lang="EN-US" style="mso-fareast-language:
ZH;"><span leaf="">ubc_cs_blob_allocate</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:
ZH;"><span leaf="">分配一块内存，调用</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">vn_rdwr</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">把签名信息读取到新分配的内存里。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="shell"><code><span leaf="">if (ubc_cs_blob_add(vp,</span></code><br/><code><span leaf=""><span class="code-snippet__meta"> result-&gt;</span>ip_platform,</span></code><br/><code><span leaf=""> cputype,</span></code><br/><code><span leaf=""> cpusubtype,</span></code><br/><code><span leaf=""> macho_offset,</span></code><br/><code><span leaf=""> &amp;addr,</span></code><br/><code><span leaf=""><span class="code-snippet__meta"> lcp-&gt;</span>datasize,</span></code><br/><code><span leaf=""> imgp,</span></code><br/><code><span leaf=""> 0,</span></code><br/><code><span leaf=""> &amp;blob))</span></code><br/></pre></p><p><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">    调用</span></span><span lang="EN-US" style="mso-fareast-language:
ZH;"><span leaf="">ubc_cs_blob_add</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:
ZH;"><span leaf="">把</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">csblob</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">加入到链表中。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf=""><span class="code-snippet__function"><span class="code-snippet__type">int</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__title">ubc_cs_blob_add</span><span class="code-snippet__params">(</span></span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">struct</span> vnode    *vp,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">uint32_t</span>        platform,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">cpu_type_t</span>      cputype,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">cpu_subtype_t</span>   cpusubtype,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">off_t</span>           base_offset,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_address_t</span>    *addr,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_size_t</span>       size,</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">struct</span> image_params *imgp,</span></code><br/><code><span leaf=""> __unused <span class="code-snippet__type">int</span>    flags,</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">struct</span> cs_blob  **ret_blob)</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf="">error = <span class="code-snippet__built_in">cs_blob_init_validated</span>(addr, size, &amp;tmp_blob, &amp;cd);</span></code><br/></pre></p><p style=""><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">    首先验证签名信息的格式是否正确，这里的校验并不完全严格，请读者自行阅读。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="javascript"><code><span leaf="">blob_ro = <span class="code-snippet__title">zalloc_ro</span>(<span class="code-snippet__variable">ZONE_ID_CS_BLOB</span>, <span class="code-snippet__variable">Z_WAITOK</span> | <span class="code-snippet__variable">Z_NOFAIL</span>);</span></code><br/><code><span leaf="">tmp_blob.<span class="code-snippet__property">csb_ro_addr</span> = blob_ro;</span></code><br/><code><span leaf="">tmp_blob.<span class="code-snippet__property">csb_vnode</span> = vp;</span></code><br/><code><span leaf=""><span class="code-snippet__comment">/* AMFI needs to see the current blob state at the RO address. */</span></span></code><br/><code><span leaf=""><span class="code-snippet__title">zalloc_ro_update_elem</span>(<span class="code-snippet__variable">ZONE_ID_CS_BLOB</span>, blob_ro, &amp;tmp_blob);</span></code><br/></pre></p><p style=""><span lang="EN-US" style="background:yellow;mso-highlight:yellow;mso-fareast-language:ZH;"><span leaf="">    注意</span></span><span lang="EN-US" style="mso-fareast-language:
ZH;"><span leaf="">csblob</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:
ZH;"><span leaf="">结构体使用</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">zlloc</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">的接口将其信息通过</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">PPL</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;mso-fareast-language:ZH;"><span leaf="">保存在只读内存区，请参考后面关于</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">PPL</span></span><span lang="ZH" style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">的分析部分。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cs"><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">if</span></span><span class="code-snippet__meta"> CONFIG_MACF</span></span></code><br/><code><span leaf=""> error = mac_vnode_check_signature(vp, &amp;tmp_blob, imgp, &amp;cs_flags, &amp;signer_type, flags, platform);</span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">endif</span></span></span></code><br/><code><span leaf="">}</span></code><br/></pre></p><p><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">    mac_vnode_check_signature</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;mso-fareast-language:ZH;"><span leaf="">继续调用</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">AMFI</span></span><span lang="ZH" style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">内核模块的接口，苹果公司的签名核心技术都存放于这个内核模块中，由于不会开源，我们将在下一章使用逆向过程技术还原出它所有的核心逻辑。</span></span></p><p style=""><span lang="ZH" style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">  当</span></span><span lang="EN-US" style="mso-fareast-language:
ZH;"><span leaf="">load_code_signature</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:
ZH;"><span leaf="">返回成功后，则会调用</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">cs_validate_range</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">对所有的文件</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">hash</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;mso-fareast-language:ZH;"><span leaf="">做对比测试，确保当前计算出的</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">hash</span></span><span lang="ZH" style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">与文件加载进来的</span></span><span lang="EN-US" style="mso-fareast-language:
ZH;"><span leaf="">hash</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:
ZH;"><span leaf="">匹配。</span></span></p><p style=""><span lang="ZH" style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;background:red;mso-highlight:red;mso-fareast-language:ZH;"><span leaf="">注意：即使</span></span><span lang="EN-US" style="background:red;mso-highlight:red;mso-fareast-language:ZH;"><span leaf="">vnode</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;background:red;mso-highlight:red;mso-fareast-language:
ZH;"><span leaf="">中已经存在</span></span><span lang="EN-US" style="background:red;mso-highlight:red;mso-fareast-language:ZH;"><span leaf="">csblob</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;background:red;mso-highlight:red;mso-fareast-language:ZH;"><span leaf="">信息，它只是不在走</span></span><span lang="EN-US" style="background:red;mso-highlight:red;mso-fareast-language:ZH;"><span leaf="">AMFI</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;background:red;mso-highlight:red;mso-fareast-language:
ZH;"><span leaf="">的流程，对所有文件的</span></span><span lang="EN-US" style="background:red;mso-highlight:red;mso-fareast-language:ZH;"><span leaf="">hash</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;background:red;mso-highlight:red;mso-fareast-language:ZH;"><span leaf="">对比是每次都要进行的！</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;background:red;mso-highlight:red;"><span leaf="">因为保存在磁盘的时间，应用程序可能已经被窜改。</span></span></p><h3><span style="mso-bookmark:
_Toc633;"><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf=""><span textstyle="" style="font-size: 18px;font-weight: bold;">3.1.2 运行时验签过程</span></span></span></span></h3><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">    进程在启动时</span></span><span lang="EN-US"><span leaf="">ios</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">已经做了一次签名验证，</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">但是在进程运行的过程中，代码和数据还是可能被篡改掉的，那么如何在进程的运行过程中进行签名的验证呢？</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">它的验签逻辑可以发生在进程调度、系统调用过程、</span></span><span lang="EN-US"><span leaf="">page fault</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">甚至可以开一个单独的线程每隔一定时间进行轮询验签，但是作为一个工业级的</span></span><span lang="EN-US"><span leaf="">os</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，需要考虑性能功耗的问题。</span></span><span lang="EN-US"><span leaf="">ios</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">选择了在</span></span><span lang="EN-US"><span leaf="">page fault</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">中做代码的</span></span><span lang="EN-US"><span leaf="">hash</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">值对比操作。</span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">    引起</span></span><span lang="EN-US"><span leaf="">Page fault</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">的原因有很多种，有发生在内核空间中的，有发生在用户空间中的，比如应用程序越界访问内核、应用程序对只读内存进行写操作，还有应用程序访问自身一段还没有被映射的页面，这个错误可以引发</span></span><span lang="EN-US"><span leaf="">Copy on write</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">动作或者这个页面之前被交换到磁盘上，那么在页面换回时，势必要再进行一次签名验证。</span></span></p><h4><span lang="EN-US"><span leaf=""><span textstyle="" style="font-weight: bold;">3.1.2.1 </span></span></span><span style="font-family:黑体;mso-ascii-font-family:
Arial;mso-hansi-font-family:Arial;"><span leaf=""><span textstyle="" style="font-weight: bold;">权限错误处理流程</span></span></span></h4><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">    在进行异常处理前，需要先判断一下引起这个</span></span><span lang="EN-US"><span leaf="">fault</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">的物理页是否需要做一次签名验证，因为如果这块物理页已经被污染过，那么起始没必要进行</span></span><span lang="EN-US"><span leaf="">fault</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">处理了。如果没被污染，</span></span><span lang="EN-US"><span leaf=""> ios</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">也有一些优化可以快速避开本次验签过程。</span></span><span lang="EN-US"><span leaf="">vm_fault_cs_check_violation</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">函数就是用来做这些事情。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf=""><span class="code-snippet__built_in">vm_fault_cs_check_violation</span>(</span></code><br/><code><span leaf=""> <span class="code-snippet__type">bool</span> cs_bypass,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_object_t</span> object,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_page_t</span> m,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">pmap_t</span> pmap,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_prot_t</span> prot,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_prot_t</span> caller_prot,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_map_size_t</span> fault_page_size,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_map_offset_t</span> fault_phys_offset,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_object_fault_info_t</span> fault_info,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">bool</span> map_is_switched,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">bool</span> map_is_switch_protected,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">bool</span> *cs_violation)</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (!cs_bypass &amp;&amp;</span></code><br/><code><span leaf="">     <span class="code-snippet__built_in">vm_fault_cs_need_validation</span>(pmap, m, object,</span></code><br/><code><span leaf="">     fault_page_size, fault_phys_offset)) {</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">vm_object_lock_assert_exclusive</span>(object);</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (<span class="code-snippet__built_in">VMP_CS_VALIDATED</span>(m, fault_page_size, fault_phys_offset)) {</span></code><br/><code><span leaf=""> vm_cs_revalidates++;</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">vm_page_validate_cs</span>(m, fault_page_size, fault_phys_offset);</span></code><br/><code><span leaf="">}</span></code><br/><code><span leaf="">}</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    vm_fault_cs_need_validation</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">用来判断这个物理页是否需要进行验签过程。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf=""><span class="code-snippet__function"><span class="code-snippet__type">static</span></span><span class="code-snippet__function"><span class="code-snippet__type">bool</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__title">vm_fault_cs_need_validation</span><span class="code-snippet__params">(</span></span></code><br/><code><span leaf=""> <span class="code-snippet__type">pmap_t</span> pmap,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_page_t</span> page,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_object_t</span> page_obj,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_map_size_t</span> fault_page_size,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_map_offset_t</span> fault_phys_offset)</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (pmap == kernel_pmap) {</span></code><br/><code><span leaf=""> <span class="code-snippet__comment">/* 1 - not user space */</span></span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">return</span> <span class="code-snippet__literal">false</span>;</span></code><br/><code><span leaf=""> }</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    验签只针对用户态代码和数据。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="kotlin"><code><span leaf=""> <span class="code-snippet__keyword">if</span> (!page_obj-&gt;code_signed) {</span></code><br/><code><span leaf=""> <span class="code-snippet__comment">/* 3 - page does not belong to a code-signed object */</span></span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">return</span> <span class="code-snippet__literal">false</span>;</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (fault_page_size == PAGE_SIZE) {</span></code><br/><code><span leaf=""> <span class="code-snippet__comment">/* looking at the whole page */</span></span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (page-&gt;vmp_cs_tainted == VMP_CS_ALL_TRUE) {</span></code><br/><code><span leaf=""> <span class="code-snippet__comment">/* 2 - page is all tainted */</span></span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">return</span> <span class="code-snippet__literal">false</span>;</span></code><br/><code><span leaf=""> }</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    如果这个物理页已经被污染掉，此次就不在需要再判断了。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="kotlin"><code><span leaf=""> <span class="code-snippet__keyword">if</span> (page-&gt;vmp_cs_validated == VMP_CS_ALL_TRUE &amp;&amp;</span></code><br/><code><span leaf="">     !page-&gt;vmp_wpmapped) {</span></code><br/><code><span leaf=""> <span class="code-snippet__comment">/* 4 - already fully validated and never mapped writable */</span></span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">return</span> <span class="code-snippet__literal">false</span>;</span></code><br/><code><span leaf=""> }</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    如果这个物理页此前已经被处理过，那么此次</span></span><span lang="EN-US"><span leaf="">fault</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">也不会再判断了。</span></span><span lang="EN-US"><span leaf="">Ios</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">的</span></span><span lang="EN-US"><span leaf="">jit</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">签名就是利用了这一点绕过了签名的验证。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf="">} <span class="code-snippet__keyword">else</span> {</span></code><br/><code><span leaf=""> <span class="code-snippet__comment">/* looking at a specific sub-page */</span></span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (<span class="code-snippet__built_in">VMP_CS_TAINTED</span>(page, fault_page_size, fault_phys_offset)) {</span></code><br/><code><span leaf=""> <span class="code-snippet__comment">/* 2 - sub-page was already marked as tainted */</span></span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">return</span> <span class="code-snippet__literal">false</span>;</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (<span class="code-snippet__built_in">VMP_CS_VALIDATED</span>(page, fault_page_size, fault_phys_offset) &amp;&amp;</span></code><br/><code><span leaf="">     !page-&gt;vmp_wpmapped) {</span></code><br/><code><span leaf=""> <span class="code-snippet__comment">/* 4 - already validated and never mapped writable */</span></span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">return</span> <span class="code-snippet__literal">false</span>;</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> <span class="code-snippet__comment">/* page needs to be validated */</span></span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">return</span> <span class="code-snippet__literal">true</span>;</span></code><br/><code><span leaf="">}</span></code><br/><code><span leaf=""><span class="code-snippet__function"><span class="code-snippet__type">void</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__title">vm_page_validate_cs</span><span class="code-snippet__params">(</span></span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_page_t</span>       page,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_map_size_t</span>   fault_page_size,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_map_offset_t</span> fault_phys_offset)</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_object_t</span>             object;</span></code><br/><code><span leaf=""> object = <span class="code-snippet__built_in">VM_PAGE_OBJECT</span>(page);</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">vm_object_lock_assert_held</span>(object);</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (<span class="code-snippet__built_in">vm_page_validate_cs_fast</span>(page, fault_page_size, fault_phys_offset)) {</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">return</span>;</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">vm_page_map_and_validate_cs</span>(object, page);</span></code><br/><code><span leaf="">}</span></code><br/><code><span leaf=""><span class="code-snippet__function"><span class="code-snippet__type">static</span></span><span class="code-snippet__function"><span class="code-snippet__type">boolean_t</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__title">vm_page_validate_cs_fast</span><span class="code-snippet__params">(</span></span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_page_t</span>       page,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_map_size_t</span>   fault_page_size,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_map_offset_t</span> fault_phys_offset)</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_object_t</span>     object;</span></code><br/><code><span leaf=""> object = <span class="code-snippet__built_in">VM_PAGE_OBJECT</span>(page);</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">vm_object_lock_assert_held</span>(object);</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (page-&gt;vmp_wpmapped&amp;&amp;</span></code><br/><code><span leaf="">     !<span class="code-snippet__built_in">VMP_CS_TAINTED</span>(page, fault_page_size, fault_phys_offset)) {</span></code><br/><code><span leaf=""> <span class="code-snippet__comment">/*</span></span></code><br/><code><span leaf="">  * This page was mapped for &#34;write&#34; access sometime in the</span></code><br/><code><span leaf="">  * past and could still be modifiable in the future.</span></code><br/><code><span leaf="">  * Consider it tainted.</span></code><br/><code><span leaf="">  * [ If the page was already found to be &#34;tainted&#34;, no</span></code><br/><code><span leaf="">  * need to re-validate. ]</span></code><br/><code><span leaf="">  */</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">vm_object_lock_assert_exclusive</span>(object);</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">VMP_CS_SET_VALIDATED</span>(page, fault_page_size, fault_phys_offset, TRUE);</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">VMP_CS_SET_TAINTED</span>(page, fault_page_size, fault_phys_offset, TRUE);</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (cs_debug) {</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">printf</span>(<span class="code-snippet__string">&#34;CODESIGNING: %s: &#34;</span></span></code><br/><code><span leaf="">     <span class="code-snippet__string">&#34;page %p obj %p off 0x%llx &#34;</span></span></code><br/><code><span leaf="">     <span class="code-snippet__string">&#34;was modified\n&#34;</span>,</span></code><br/><code><span leaf="">     __FUNCTION__,</span></code><br/><code><span leaf="">     page, object, page-&gt;vmp_offset);</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> vm_cs_validated_dirtied++;</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (<span class="code-snippet__built_in">VMP_CS_VALIDATED</span>(page, fault_page_size, fault_phys_offset) ||</span></code><br/><code><span leaf="">     <span class="code-snippet__built_in">VMP_CS_TAINTED</span>(page, fault_page_size, fault_phys_offset)) {</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">return</span> TRUE;</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf="">}</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    vm_page_validate_cs_fast</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">有个特殊的处理，如果</span></span><span lang="EN-US"><span leaf="">page-&gt;vmp_wpmapped</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">被设置，说明这个物理页在之前的某段时间里被设置为可写状态，</span></span><span lang="EN-US"><span leaf="">xnu</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">认为在将来的一段时间这个可写状态会一直保持，所以直接将这个物理页标记为污染和审计过，直接返回。</span></span></p><p style=""><span lang="EN-US"><span leaf="">    vm_page_map_and_validate_cs</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">函数则对这个物理页做</span></span><span lang="EN-US"><span leaf="">hash</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">对比操作，读者可自行阅读相关代码。</span></span></p><h4><span lang="EN-US"><span leaf=""><span textstyle="" style="font-weight: bold;">3.1.2.2 </span></span></span><span style="font-family:黑体;mso-ascii-font-family:
Arial;mso-hansi-font-family:Arial;"><span leaf=""><span textstyle="" style="font-weight: bold;">磁盘交换处理流程</span></span></span></h4><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">    接下来就要分析页面从磁盘交换回内存时的签名验证过程</span></span><span lang="EN-US"><span leaf="">:</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf="">Osfmk/vm/vm_fault.c</span></code><br/><code><span leaf="">vm_fault_page-&gt;memory_object_data_request</span></code><br/><code><span leaf="">Osfmk/vm/memory_object.<span class="code-snippet__function">c</span></span></code><br/><code><span leaf=""><span class="code-snippet__type">kern_return_t</span></span></code><br/><code><span leaf=""><span class="code-snippet__title">memory_object_data_request</span></span></code><br/><code><span leaf=""><span class="code-snippet__params">(</span></span></code><br/><code><span leaf=""> <span class="code-snippet__type">memory_object_t</span> memory_object,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">memory_object_offset_t</span> offset,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">memory_object_cluster_size_t</span> length,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_prot_t</span> desired_access,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">memory_object_fault_info_t</span> fault_info</span></code><br/><code><span leaf="">)</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">return</span> (memory_object-&gt;mo_pager_ops-&gt;memory_object_data_request)(</span></code><br/><code><span leaf=""> memory_object,</span></code><br/><code><span leaf=""> offset,</span></code><br/><code><span leaf=""> length,</span></code><br/><code><span leaf=""> desired_access,</span></code><br/><code><span leaf=""> fault_info);</span></code><br/><code><span leaf="">}</span></code><br/></pre></p><p style=""><span lang="EN-US"><span leaf="">    xnu</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">提供了几种不同的内存后备存储方式，比如</span></span><span lang="EN-US"><span leaf="">swap</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">交换文件、普通文件、内存压缩、</span></span><span lang="EN-US"><span leaf=""> apple</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">特有的内存加密方式，这些后备存储都对应不同的分页器，但只有几种后备存储才会在内存交换回来时做签名验证</span></span><span lang="EN-US"><span leaf="">, </span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">这里我们只以</span></span><span lang="EN-US"><span leaf="">4k</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">形式的分页器进行分析。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf="">Osfmk/vm/vm_fourk_pager.c</span></code><br/><code><span leaf=""><span class="code-snippet__type">const</span> <span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">memory_object_pager_ops</span> fourk_pager_ops = {</span></code><br/><code><span leaf=""> .memory_object_reference = fourk_pager_reference,</span></code><br/><code><span leaf=""> .memory_object_deallocate = fourk_pager_deallocate,</span></code><br/><code><span leaf=""> .memory_object_init = fourk_pager_init,</span></code><br/><code><span leaf=""> .memory_object_terminate = fourk_pager_terminate,</span></code><br/><code><span leaf=""> .memory_object_data_request = fourk_pager_data_request,</span></code><br/><code><span leaf=""> .memory_object_data_return = fourk_pager_data_return,</span></code><br/><code><span leaf=""> .memory_object_data_initialize = fourk_pager_data_initialize,</span></code><br/><code><span leaf=""> .memory_object_data_unlock = fourk_pager_data_unlock,</span></code><br/><code><span leaf=""> .memory_object_synchronize = fourk_pager_synchronize,</span></code><br/><code><span leaf=""> .memory_object_map = fourk_pager_map,</span></code><br/><code><span leaf=""> .memory_object_last_unmap = fourk_pager_last_unmap,</span></code><br/><code><span leaf=""> .memory_object_data_reclaim = <span class="code-snippet__literal">NULL</span>,</span></code><br/><code><span leaf=""> .memory_object_backing_object = <span class="code-snippet__literal">NULL</span>,</span></code><br/><code><span leaf=""> .memory_object_pager_name = <span class="code-snippet__string">&#34;fourk_pager&#34;</span></span></code><br/><code><span leaf="">};</span></code><br/><code><span leaf=""><span class="code-snippet__built_in">fourk_pager_data_request</span>(</span></code><br/><code><span leaf=""> <span class="code-snippet__type">memory_object_t</span>         mem_obj,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">memory_object_offset_t</span>  offset,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">memory_object_cluster_size_t</span>            length,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_prot_t</span>               protection_required,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">memory_object_fault_info_t</span> mo_fault_info)</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""> subpg_validated = FALSE;</span></code><br/><code><span leaf=""> subpg_tainted = <span class="code-snippet__number">0</span>;</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (src_page_object-&gt;code_signed) {</span></code><br/><code><span leaf="">          <span class="code-snippet__built_in">vm_page_validate_cs_mapped_chunk</span>(</span></code><br/><code><span leaf=""> src_page,</span></code><br/><code><span leaf=""> (<span class="code-snippet__type">const</span> <span class="code-snippet__type">void</span> *) src_vaddr,</span></code><br/><code><span leaf=""> offset_in_src_page,</span></code><br/><code><span leaf=""> FOURK_PAGE_SIZE,</span></code><br/><code><span leaf=""> &amp;subpg_validated,</span></code><br/><code><span leaf=""> &amp;subpg_tainted);</span></code><br/><code><span leaf=""> num_subpg_signed++;</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (subpg_validated) {</span></code><br/><code><span leaf=""> num_subpg_validated++;</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (subpg_tainted &amp; CS_VALIDATE_TAINTED) {</span></code><br/><code><span leaf=""> num_subpg_tainted++;</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (subpg_tainted &amp; CS_VALIDATE_NX) {</span></code><br/><code><span leaf=""> <span class="code-snippet__comment">/* subpg should not be executable */</span></span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (sub_page_cnt &gt; <span class="code-snippet__number">1</span>) {</span></code><br/><code><span leaf=""> } <span class="code-snippet__keyword">else</span> {</span></code><br/><code><span leaf=""> num_subpg_nx++;</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> }</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    vm_page_validate_cs_mapped_chunk</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">对一块物理内存进行签名验证，因为在页面被交换到磁盘的这段时间内，可能会被篡改掉。</span></span></p><h4><span lang="EN-US"><span leaf=""><span textstyle="" style="font-weight: bold;">3.1.2.3 </span></span></span><span style="font-family:黑体;mso-ascii-font-family:
Arial;mso-hansi-font-family:Arial;"><span leaf=""><span textstyle="" style="font-weight: bold;">页面复制时</span></span></span></h4><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">    此外在进行一个物理页面的复制时，也需要对源物理页进行签名验证。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf="">osfmk\vm\vm_resident.<span class="code-snippet__function">c</span></span></code><br/><code><span leaf=""><span class="code-snippet__type">void</span></span></code><br/><code><span leaf=""><span class="code-snippet__title">vm_page_copy</span><span class="code-snippet__params">(</span></span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_page_t</span>       src_m,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_page_t</span>       dest_m)</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_object_t</span>     src_m_object;</span></code><br/><code><span leaf=""> src_m_object = <span class="code-snippet__built_in">VM_PAGE_OBJECT</span>(src_m);</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">vm_object_lock_assert_held</span>(src_m_object);</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (src_m_object != VM_OBJECT_NULL &amp;&amp;</span></code><br/><code><span leaf="">     src_m_object-&gt;code_signed) {</span></code><br/><code><span leaf=""> vm_page_copy_cs_validations++;</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">vm_page_validate_cs</span>(src_m, PAGE_SIZE, <span class="code-snippet__number">0</span>);</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> dest_m-&gt;vmp_cs_tainted = src_m-&gt;vmp_cs_tainted;</span></code><br/><code><span leaf=""> dest_m-&gt;vmp_cs_nx = src_m-&gt;vmp_cs_nx;</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (dest_m-&gt;vmp_cs_tainted) {</span></code><br/><code><span leaf=""> vm_page_copy_cs_tainted++;</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> dest_m-&gt;vmp_error = src_m-&gt;vmp_error; <span class="code-snippet__comment">/* sliding src_m might have failed... */</span></span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">pmap_copy_page</span>(<span class="code-snippet__built_in">VM_PAGE_GET_PHYS_PAGE</span>(src_m), <span class="code-snippet__built_in">VM_PAGE_GET_PHYS_PAGE</span>(dest_m));</span></code><br/><code><span leaf="">}</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    Src_m</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">代表源页面，如果它对应的</span></span><span lang="EN-US"><span leaf="">object</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">对象有</span></span><span lang="EN-US"><span leaf="">code_signed</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">标志，那么就会进行一次签名验证，页面拷贝需要确保它的完整性。</span></span></p><h4><span lang="EN-US"><span leaf=""><span textstyle="" style="font-weight: bold;">3.1.2.4 </span></span></span><span style="font-family:黑体;mso-ascii-font-family:
Arial;mso-hansi-font-family:Arial;"><span leaf=""><span textstyle="" style="font-weight: bold;">只读</span></span></span><span lang="EN-US"><span leaf=""><span textstyle="" style="font-weight: bold;">rootfs</span></span></span><span style="font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;"><span leaf=""><span textstyle="" style="font-weight: bold;">的优化</span></span></span></h4><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">    对于只读</span></span><span lang="EN-US"><span leaf="">rootfs</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">上的文件，</span></span><span lang="EN-US"><span leaf="">xnu</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">做了优化，在</span></span><span lang="EN-US"><span leaf="">page fault</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">第一次验证完签名后，如果当前进程没有试图将只读</span></span><span lang="EN-US"><span leaf="">rootfs</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">挂载为可写，那么后续就不再做签名验证，属于性能优化的一部分。</span></span></p><p><span lang="EN-US"><span leaf="">Bsd/sys/ubc_internal.h</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf=""><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">ubc_info</span> {</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">struct</span>  <span class="code-snippet__title">cs_blob</span>         * cs_blobs; <span class="code-snippet__comment">/* for CODE SIGNING */</span></span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">if</span></span><span class="code-snippet__meta"> CONFIG_SUPPLEMENTAL_SIGNATURES</span></span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">struct</span>  <span class="code-snippet__title">cs_blob</span>         * cs_blob_supplement;<span class="code-snippet__comment">/* supplemental blob (note that there can only be one supplement) */</span></span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">endif</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">if</span></span><span class="code-snippet__meta"> CHECK_CS_VALIDATION_BITMAP</span></span></code><br/><code><span leaf=""> <span class="code-snippet__function"><span class="code-snippet__type">void</span></span><span class="code-snippet__function">                    * </span><span class="code-snippet__function"><span class="code-snippet__title">XNU_PTRAUTH_SIGNED_PTR</span></span><span class="code-snippet__function"><span class="code-snippet__params">(</span></span><span class="code-snippet__function"><span class="code-snippet__params"><span class="code-snippet__string">&#34;ubc_info.cs_valid_bitmap&#34;</span></span></span><span class="code-snippet__function"><span class="code-snippet__params">)</span></span><span class="code-snippet__function"> cs_valid_bitmap</span>;     <span class="code-snippet__comment">/* right now: used only for signed files on the read-only root volume */</span></span></code><br/><code><span leaf=""> <span class="code-snippet__type">uint64_t</span>                cs_valid_bitmap_size;</span></code><br/><code><span leaf="">}</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    Ubc_info</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">结构体除了保存</span></span><span lang="EN-US"><span leaf="">struct cs_blob</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">结构体外，还可选的保存了一个</span></span><span lang="EN-US"><span leaf="">bitmap</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">，它用来设置一个物理页的签名状态。</span></span></p><p><span lang="EN-US"><span leaf="">Osfmk/vm/vm_protos.h</span></span></p><p><span lang="EN-US"><span leaf=""><a class="wx_topic_link" topic-id="mjxirzjq-gjkevr" style="color: #576B95 !important;" data-topic="1">#define</a> CS_BITMAP_SET</span><span leaf="">1</span><span leaf="">//</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">对页面设置为已经检查过</span></span></p><p><span lang="EN-US"><span leaf=""><a class="wx_topic_link" topic-id="mjxirzjq-o16lv2" style="color: #576B95 !important;" data-topic="1">#define</a> CS_BITMAP_CLEAR 2</span><span leaf="">// </span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">清除签名状态</span></span></p><p><span lang="EN-US"><span leaf=""><a class="wx_topic_link" topic-id="mjxirzjq-ji7y4f" style="color: #576B95 !important;" data-topic="1">#define</a> CS_BITMAP_CHECK 3</span><span leaf="">// </span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">对页面进行签名检查</span></span></p><p style=""><span lang="EN-US"><span leaf="">vm_page_validate_cs_fast</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">函数前面讲过它会进行预判此次</span></span><span lang="EN-US"><span leaf="">page fault</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">是否需要验证这个页面的签名。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf=""><span class="code-snippet__function"><span class="code-snippet__type">static</span></span><span class="code-snippet__function"><span class="code-snippet__type">boolean_t</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__title">vm_page_validate_cs_fast</span><span class="code-snippet__params">(</span></span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_page_t</span>       page,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_map_size_t</span>   fault_page_size,</span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_map_offset_t</span> fault_phys_offset)</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">if</span></span><span class="code-snippet__meta"> CHECK_CS_VALIDATION_BITMAP</span></span></code><br/><code><span leaf=""> <span class="code-snippet__type">kern_return_t</span> kr;</span></code><br/><code><span leaf=""> kr = <span class="code-snippet__built_in">vnode_pager_cs_check_validation_bitmap</span>(</span></code><br/><code><span leaf=""> object-&gt;pager,</span></code><br/><code><span leaf=""> page-&gt;vmp_offset + object-&gt;paging_offset,</span></code><br/><code><span leaf=""> CS_BITMAP_CHECK);</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (kr == KERN_SUCCESS) {</span></code><br/><code><span leaf=""> page-&gt;vmp_cs_validated = VMP_CS_ALL_TRUE;</span></code><br/><code><span leaf=""> page-&gt;vmp_cs_tainted = VMP_CS_ALL_FALSE;</span></code><br/><code><span leaf=""> vm_cs_bitmap_validated++;</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">return</span> TRUE;</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">endif</span></span></span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">  它会调用</span></span><span lang="EN-US"><span leaf="">vnode_pager_cs_check_validation_bitmap</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">传递</span></span><span lang="EN-US"><span leaf="">CS_BITMAP_CHECK</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">进行判断是否需要签名验证。</span></span></p><p style=""><span lang="EN-US"><span leaf="">vnode_pager_cs_check_validation_bitmap</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">进一步调用</span></span><span lang="EN-US"><span leaf="">ubc_cs_check_validation_bitmap</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cs"><code><span leaf=""><span class="code-snippet__function">kern_return_t</span></span></code><br/><code><span leaf=""><span class="code-snippet__title">ubc_cs_check_validation_bitmap</span>(</span></code><br/><code><span leaf=""> vnode_t                 vp,</span></code><br/><code><span leaf=""> memory_object_offset_t          offset,</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">int</span>                     optype)</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""> kern_return_t   kr = KERN_SUCCESS;</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (!USE_CODE_SIGN_BITMAP(vp)|| !UBCINFOEXISTS(vp)) {              【<span class="code-snippet__number">1</span>】</span></code><br/><code><span leaf=""> kr = KERN_INVALID_ARGUMENT;</span></code><br/><code><span leaf=""> } <span class="code-snippet__keyword">else</span> {</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">struct</span> ubc_info *uip = vp-&gt;v_ubcinfo;</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">char</span>            *target_bitmap = uip-&gt;cs_valid_bitmap;</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (target_bitmap == NULL) {</span></code><br/><code><span leaf=""> kr = KERN_INVALID_ARGUMENT;</span></code><br/><code><span leaf=""> } <span class="code-snippet__keyword">else</span> {</span></code><br/><code><span leaf=""> uint64_t        bit, <span class="code-snippet__built_in">byte</span>;</span></code><br/><code><span leaf=""> bit = atop_64( offset );</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">byte</span> = bit &gt;&gt; <span class="code-snippet__number">3</span>;</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (<span class="code-snippet__built_in">byte</span> &gt; uip-&gt;cs_valid_bitmap_size) {</span></code><br/><code><span leaf=""> kr = KERN_INVALID_ARGUMENT;</span></code><br/><code><span leaf=""> } <span class="code-snippet__keyword">else</span> {</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (optype == CS_BITMAP_SET) {</span></code><br/><code><span leaf=""> target_bitmap[<span class="code-snippet__built_in">byte</span>] |= (<span class="code-snippet__number">1</span> &lt;&lt; (bit &amp; <span class="code-snippet__number">07</span>));</span></code><br/><code><span leaf=""> kr = KERN_SUCCESS;</span></code><br/><code><span leaf=""> } <span class="code-snippet__keyword">else</span> <span class="code-snippet__keyword">if</span> (optype == CS_BITMAP_CLEAR) {</span></code><br/><code><span leaf=""> target_bitmap[<span class="code-snippet__built_in">byte</span>] &amp;= ~(<span class="code-snippet__number">1</span> &lt;&lt; (bit &amp; <span class="code-snippet__number">07</span>));</span></code><br/><code><span leaf=""> kr = KERN_SUCCESS;</span></code><br/><code><span leaf=""> } <span class="code-snippet__keyword">else</span> <span class="code-snippet__keyword">if</span> (optype == CS_BITMAP_CHECK) {</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (target_bitmap[<span class="code-snippet__built_in">byte</span>] &amp; (<span class="code-snippet__number">1</span> &lt;&lt; (bit &amp; <span class="code-snippet__number">07</span>))) {           【<span class="code-snippet__number">2</span>】</span></code><br/><code><span leaf=""> kr = KERN_SUCCESS;</span></code><br/><code><span leaf=""> } <span class="code-snippet__keyword">else</span> {</span></code><br/><code><span leaf=""> kr = KERN_FAILURE;</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">return</span> kr;</span></code><br/><code><span leaf="">}</span></code><br/></pre></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="sql"><code><span leaf="">#<span class="code-snippet__keyword">define</span> USE_CODE_SIGN_BITMAP(vp) ( (vp <span class="code-snippet__operator">!=</span> <span class="code-snippet__keyword">NULL</span>) <span class="code-snippet__operator">&amp;&amp;</span> (vp<span class="code-snippet__operator">-&gt;</span>v_mount <span class="code-snippet__operator">!=</span> <span class="code-snippet__keyword">NULL</span>) <span class="code-snippet__operator">&amp;&amp;</span> (vp<span class="code-snippet__operator">-&gt;</span>v_mount<span class="code-snippet__operator">-&gt;</span>mnt_flag <span class="code-snippet__operator">&amp;</span> MNT_ROOTFS) <span class="code-snippet__operator">&amp;&amp;</span> <span class="code-snippet__operator">!</span>root_fs_upgrade_try)</span></code></pre></p><p><span lang="EN-US"><span leaf="">    USE_CODE_SIGN_BITMAP</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">这个首先宏判断</span></span><span lang="EN-US"><span leaf="">vnode</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">是不是</span></span><span lang="EN-US"><span leaf="">rootfs</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，并且要判断</span></span><span lang="EN-US"><span leaf="">root_fs_upgrade_try</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">是否为</span></span><span lang="EN-US"><span leaf="">0</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。这个变量代表的是进程试图将只读的文件系统挂载为可写。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf=""><span class="code-snippet__type">boolean_t</span> root_fs_upgrade_try = FALSE;</span></code><br/><code><span leaf=""><span class="code-snippet__type">int</span></span></code><br/><code><span leaf="">__mac_mount(<span class="code-snippet__keyword">struct</span> proc *p, <span class="code-snippet__keyword">register</span> <span class="code-snippet__keyword">struct</span> __mac_mount_args *uap, __unused <span class="code-snippet__type">int32_t</span> *retval)</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">if</span></span><span class="code-snippet__meta"> CHECK_CS_VALIDATION_BITMAP</span></span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> ((flags &amp; MNT_RDONLY) == <span class="code-snippet__number">0</span>) {</span></code><br/><code><span leaf=""> root_fs_upgrade_try = TRUE;</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">endif</span></span></span></code><br/><code><span leaf="">}</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">  所以【</span></span><span lang="EN-US"><span leaf="">1</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">】处的逻辑为：如果</span></span><span lang="EN-US"><span leaf="">vnode</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">属于</span></span><span lang="EN-US"><span leaf="">rootfs</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，并且</span></span><span lang="EN-US"><span leaf="">root_fs_upgrade_try</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">设置为了</span></span><span lang="EN-US"><span leaf="">1</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，说明有进程将只读</span></span><span lang="EN-US"><span leaf="">rootfs</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">重新挂载为可写，那么就必须对这个物理页进行签名验证，否则在【</span></span><span lang="EN-US"><span leaf="">2</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">】处要进行一次页面曾经是否被检测过的判断，如果对应的比特位已经被设置，则无需进行签名验证，否则需要进行签名验证。我们看到</span></span><span lang="EN-US"><span leaf="">CS_BITMAP_CHECK</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">是用来判断比特位是否设置的，那么</span></span><span lang="EN-US"><span leaf="">CS_BITMAP_SET</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">是在什么时候调用的呢？答案在</span></span><span lang="EN-US"><span leaf="">vm_page_validate_cs_mapped_slow</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">中。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cs"><code><span leaf=""><span class="code-snippet__function"><span class="code-snippet__keyword">void</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__title">vm_page_validate_cs_mapped_slow</span>(</span></code><br/><code><span leaf=""> vm_page_t       page,</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">const</span> <span class="code-snippet__keyword">void</span>      *kaddr)</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""> vm_object_t             <span class="code-snippet__built_in">object</span>;</span></code><br/><code><span leaf=""> memory_object_offset_t  mo_offset;</span></code><br/><code><span leaf=""> memory_object_t         pager;</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">struct</span> vnode            *vnode;</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">int</span>                     validated, tainted, nx;</span></code><br/><code><span leaf=""> assert(page-&gt;vmp_busy);</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">object</span> = VM_PAGE_OBJECT(page);</span></code><br/><code><span leaf=""> vm_object_lock_assert_exclusive(<span class="code-snippet__built_in">object</span>);</span></code><br/><code><span leaf=""> vm_cs_validates++;</span></code><br/><code><span leaf=""> pager = <span class="code-snippet__built_in">object</span>-&gt;pager;</span></code><br/><code><span leaf=""> assert(<span class="code-snippet__built_in">object</span>-&gt;paging_in_progress);</span></code><br/><code><span leaf=""> vnode = vnode_pager_lookup_vnode(pager);</span></code><br/><code><span leaf=""> mo_offset = page-&gt;vmp_offset + <span class="code-snippet__built_in">object</span>-&gt;paging_offset;</span></code><br/><code><span leaf=""> <span class="code-snippet__comment">/* verify the SHA1 hash for this page */</span></span></code><br/><code><span leaf=""> validated = <span class="code-snippet__number">0</span>;</span></code><br/><code><span leaf=""> tainted = <span class="code-snippet__number">0</span>;</span></code><br/><code><span leaf=""> nx = <span class="code-snippet__number">0</span>;</span></code><br/><code><span leaf=""> cs_validate_page(vnode,</span></code><br/><code><span leaf="">     pager,</span></code><br/><code><span leaf="">     mo_offset,</span></code><br/><code><span leaf="">     (<span class="code-snippet__keyword">const</span> <span class="code-snippet__keyword">void</span> *)((<span class="code-snippet__keyword">const</span> <span class="code-snippet__built_in">char</span> *)kaddr),</span></code><br/><code><span leaf="">     &amp;validated,</span></code><br/><code><span leaf="">     &amp;tainted,</span></code><br/><code><span leaf="">     &amp;nx);</span></code><br/><code><span leaf=""> page-&gt;vmp_cs_validated |= validated;</span></code><br/><code><span leaf=""> page-&gt;vmp_cs_tainted |= tainted;</span></code><br/><code><span leaf=""> page-&gt;vmp_cs_nx |= nx;</span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">if</span></span><span class="code-snippet__meta"> CHECK_CS_VALIDATION_BITMAP</span></span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (page-&gt;vmp_cs_validated == VMP_CS_ALL_TRUE &amp;&amp;</span></code><br/><code><span leaf="">     page-&gt;vmp_cs_tainted == VMP_CS_ALL_FALSE) {</span></code><br/><code><span leaf=""> vnode_pager_cs_check_validation_bitmap(<span class="code-snippet__built_in">object</span>-&gt;pager,</span></code><br/><code><span leaf="">     mo_offset,</span></code><br/><code><span leaf="">     CS_BITMAP_SET);</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">endif</span></span><span class="code-snippet__meta"> /* CHECK_CS_VALIDATION_BITMAP */</span></span></code><br/><code><span leaf="">}</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    cs_validate_page</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">对物理页进行</span></span><span lang="EN-US"><span leaf="">hash</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">值验证，如果合法，则调用</span></span><span lang="EN-US"><span leaf="">vnode_pager_cs_check_validation_bitmap</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">传递</span></span><span lang="EN-US"><span leaf="">CS_BITMAP_SET</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">对相应比特位进行了设置。此后</span></span><span lang="EN-US"><span leaf="">ubc_cs_check_validation_bitmap</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">发现如果页面比特位已经被设置，后面就无需再进行签名验证了。</span></span></p><h3><span style="mso-bookmark:_Toc24529;"><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf=""><span textstyle="" style="font-size: 18px;font-weight: bold;">3.1.3 进程退出时签名验证</span></span></span></span></h3><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">    在进程正常退出时，</span></span><span lang="EN-US"><span leaf="">xnu</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">是不会做签名验证的，只有在异常退出时，且有以下几种情况就会必须验证签名：当进程收到</span></span><span lang="EN-US"><span leaf="">coredump</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">或</span></span><span lang="EN-US"><span leaf="">crash report</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">信号时，或者因进程签名验证失败收到</span></span><span lang="EN-US"><span leaf="">CS_KILLED</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">信号时。</span></span></p><p><span lang="EN-US"><span leaf="">Bsd/kern/kern_exit.c</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf=""><span class="code-snippet__function"><span class="code-snippet__type">void</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__title">proc_prepareexit</span><span class="code-snippet__params">(</span><span class="code-snippet__params"><span class="code-snippet__type">proc_t</span></span><span class="code-snippet__params"> p, </span><span class="code-snippet__params"><span class="code-snippet__type">int</span></span><span class="code-snippet__params"> rv, </span><span class="code-snippet__params"><span class="code-snippet__type">boolean_t</span></span><span class="code-snippet__params"> perf_notify)</span></span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""> <span class="code-snippet__comment">/*</span></span></code><br/><code><span leaf="">  * Generate a corefile/crashlog if:</span></code><br/><code><span leaf="">  *     The process doesn&#39;t have an exit reason that indicates no crash report should be created</span></code><br/><code><span leaf="">  *     AND any of the following are true:</span></code><br/><code><span leaf="">  *     - The process was terminated due to a fatal signal that generates a core</span></code><br/><code><span leaf="">  *     - The process was killed due to a code signing violation</span></code><br/><code><span leaf="">  *     - The process has an exit reason that indicates we should generate a crash report</span></code><br/><code><span leaf="">  *</span></code><br/><code><span leaf="">  * The first condition is necessary because abort_with_reason()/payload() use SIGABRT</span></code><br/><code><span leaf="">  * (which normally triggers a core) but may indicate that no crash report should be created.</span></code><br/><code><span leaf="">  */</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (!(<span class="code-snippet__built_in">PROC_HAS_EXITREASON</span>(p) &amp;&amp; (<span class="code-snippet__built_in">PROC_EXITREASON_FLAGS</span>(p) &amp; OS_REASON_FLAG_NO_CRASH_REPORT)) &amp;&amp;</span></code><br/><code><span leaf="">     (<span class="code-snippet__built_in">hassigprop</span>(<span class="code-snippet__built_in">WTERMSIG</span>(rv), SA_CORE) || ((<span class="code-snippet__built_in">proc_getcsflags</span>(p) &amp; CS_KILLED) != <span class="code-snippet__number">0</span>) ||</span></code><br/><code><span leaf="">     (<span class="code-snippet__built_in">PROC_HAS_EXITREASON</span>(p) &amp;&amp; (<span class="code-snippet__built_in">PROC_EXITREASON_FLAGS</span>(p) &amp;</span></code><br/><code><span leaf="">     OS_REASON_FLAG_GENERATE_CRASH_REPORT)))) {</span></code><br/><code><span leaf=""> <span class="code-snippet__type">task_t</span> task = <span class="code-snippet__built_in">proc_task</span>(p);</span></code><br/><code><span leaf=""> <span class="code-snippet__type">uintptr_t</span> bt[<span class="code-snippet__number">2</span>];</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">backtrace_user_info</span> btinfo = BTUINFO_INIT;</span></code><br/><code><span leaf=""> <span class="code-snippet__type">unsigned</span> <span class="code-snippet__type">int</span> frame_count = <span class="code-snippet__built_in">backtrace_user</span>(bt, <span class="code-snippet__number">2</span>, <span class="code-snippet__literal">NULL</span>, &amp;btinfo);            [<span class="code-snippet__number">1</span>]</span></code><br/><code><span leaf=""> <span class="code-snippet__type">int</span> bt_err = btinfo.btui_error;</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (bt_err == <span class="code-snippet__number">0</span> &amp;&amp; frame_count &gt;= <span class="code-snippet__number">1</span>) {</span></code><br/><code><span leaf=""> <span class="code-snippet__comment">/*</span></span></code><br/><code><span leaf="">  * First check at the page containing the current PC.</span></code><br/><code><span leaf="">  * This passes if the page code signs -or- if we can&#39;t figure out</span></code><br/><code><span leaf="">  * what is at that address. The latter action is so we continue checking</span></code><br/><code><span leaf="">  * previous pages which may be corrupt and caused a wild branch.</span></code><br/><code><span leaf="">  */</span></code><br/><code><span leaf=""> kr = <span class="code-snippet__built_in">revalidate_text_page</span>(task,bt[<span class="code-snippet__number">0</span>]);                               [<span class="code-snippet__number">2</span>]</span></code><br/><code><span leaf=""> <span class="code-snippet__comment">/* No corruption found, check the previous sequential page */</span></span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (kr == KERN_SUCCESS) {</span></code><br/><code><span leaf=""> kr = <span class="code-snippet__built_in">revalidate_text_page</span>(task,bt[<span class="code-snippet__number">0</span>] - <span class="code-snippet__built_in">get_task_page_size</span>(task));     [<span class="code-snippet__number">3</span>]</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> <span class="code-snippet__comment">/* Still no corruption found, check the current function&#39;s caller */</span></span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (kr == KERN_SUCCESS) {</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (frame_count &gt; <span class="code-snippet__number">1</span> &amp;&amp;</span></code><br/><code><span leaf="">     <span class="code-snippet__built_in">atop</span>(bt[<span class="code-snippet__number">0</span>]) != <span class="code-snippet__built_in">atop</span>(bt[<span class="code-snippet__number">1</span>]) &amp;&amp;           <span class="code-snippet__comment">/* don&#39;t recheck PC page */</span></span></code><br/><code><span leaf="">     <span class="code-snippet__built_in">atop</span>(bt[<span class="code-snippet__number">0</span>]) - <span class="code-snippet__number">1</span> != <span class="code-snippet__built_in">atop</span>(bt[<span class="code-snippet__number">1</span>])) {       <span class="code-snippet__comment">/* don&#39;t recheck page before */</span></span></code><br/><code><span leaf=""> kr = <span class="code-snippet__built_in">revalidate_text_page</span>(task, (<span class="code-snippet__type">vm_map_offset_t</span>)bt[<span class="code-snippet__number">1</span>]);       [<span class="code-snippet__number">4</span>]</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (kr != KERN_SUCCESS) {</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">os_log</span>(OS_LOG_DEFAULT,</span></code><br/><code><span leaf="">     <span class="code-snippet__string">&#34;Text page corruption detected in dying process %d\n&#34;</span>, <span class="code-snippet__built_in">proc_getpid</span>(p));</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> }</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    在</span></span><span lang="EN-US"><span leaf="">[1]</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">处先获取当前函数栈的</span></span><span lang="EN-US"><span leaf="">backtrace</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">信息，</span></span><span lang="EN-US"><span leaf="">bt[0]</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">代表当前的</span></span><span lang="EN-US"><span leaf="">PC</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">指针，</span></span><span lang="EN-US"><span leaf="">bt[1]</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">代表当前函数</span></span><span lang="EN-US"><span leaf="">caller</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">的地址。在</span></span><span lang="EN-US"><span leaf="">[2]</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">处调用</span></span><span lang="EN-US"><span leaf="">revalidate_text_page</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">对当前</span></span><span lang="EN-US"><span leaf="">pc</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">所在的物理页进行一次签名检查，如果没有问题，则在</span></span><span lang="EN-US"><span leaf="">[3]</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">处对当前</span></span><span lang="EN-US"><span leaf="">pc</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">地址所在的前一个物理页进行签名验证，没有还是没有问题，就在对函数的</span></span><span lang="EN-US"><span leaf="">caller</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">地址所在的物理页进行签名检测。我们看到这一系列操作只是试图检测当前</span></span><span lang="EN-US"><span leaf="">pc</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">附近的代码段有没有被破坏。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf="">Osfmk/vm/vm_fault.<span class="code-snippet__function">c</span></span></code><br/><code><span leaf=""><span class="code-snippet__type">kern_return_t</span></span></code><br/><code><span leaf=""><span class="code-snippet__title">revalidate_text_page</span><span class="code-snippet__params">(</span><span class="code-snippet__params"><span class="code-snippet__type">task_t</span></span><span class="code-snippet__params"> task, </span><span class="code-snippet__params"><span class="code-snippet__type">vm_map_offset_t</span></span><span class="code-snippet__params"> code_addr)</span></span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""> <span class="code-snippet__type">kern_return_t</span>          kr;</span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_map_t</span>               map;</span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_object_t</span>            object = <span class="code-snippet__literal">NULL</span>;</span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_object_offset_t</span>     offset;</span></code><br/><code><span leaf=""> <span class="code-snippet__type">vm_page_t</span>              page = <span class="code-snippet__literal">NULL</span>;</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">vnode</span>           *vnode;</span></code><br/><code><span leaf=""> <span class="code-snippet__type">uint64_t</span>               *diagnose_buffer = <span class="code-snippet__literal">NULL</span>;</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">CA_EVENT_TYPE</span>(vmtc_telemetry) * event = <span class="code-snippet__literal">NULL</span>;</span></code><br/><code><span leaf=""> <span class="code-snippet__type">ca_event_t</span> ca_event = <span class="code-snippet__literal">NULL</span>;</span></code><br/><code><span leaf=""> map = task-&gt;map;</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (task-&gt;map == <span class="code-snippet__literal">NULL</span>) {</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">return</span> KERN_SUCCESS;</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> kr = <span class="code-snippet__built_in">vmtc_revalidate_lookup</span>(map, code_addr, &amp;object, &amp;offset, &amp;page);              [<span class="code-snippet__number">1</span>]</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (kr != KERN_SUCCESS) {</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">goto</span> done;</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> <span class="code-snippet__comment">/*</span></span></code><br/><code><span leaf="">  * The object needs to have a pager.</span></code><br/><code><span leaf="">  */</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (object-&gt;pager == <span class="code-snippet__literal">NULL</span>) {</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">goto</span> done;</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> <span class="code-snippet__comment">/*</span></span></code><br/><code><span leaf="">  * Needs to be a vnode backed page to have a signature.</span></code><br/><code><span leaf="">  */</span></code><br/><code><span leaf=""> vnode = <span class="code-snippet__built_in">vnode_pager_lookup_vnode</span>(object-&gt;pager);</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (vnode == <span class="code-snippet__literal">NULL</span>) {</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">goto</span> done;</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> <span class="code-snippet__comment">/*</span></span></code><br/><code><span leaf="">  * Object checks to see if we should proceed.</span></code><br/><code><span leaf="">  */</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (!object-&gt;code_signed ||     <span class="code-snippet__comment">/* no code signature to check */</span></span></code><br/><code><span leaf="">     object-&gt;internal ||         <span class="code-snippet__comment">/* internal objects aren&#39;t signed */</span></span></code><br/><code><span leaf="">     object-&gt;terminating ||      <span class="code-snippet__comment">/* the object and its pages are already going away */</span></span></code><br/><code><span leaf="">     !object-&gt;pager_ready) {     <span class="code-snippet__comment">/* this should happen, but check shouldn&#39;t hurt */</span></span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">goto</span> done;</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> <span class="code-snippet__comment">/*</span></span></code><br/><code><span leaf="">  * Check the code signature of the page in question.</span></code><br/><code><span leaf="">  */</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">vm_page_map_and_validate_cs</span>(object, page);                              [<span class="code-snippet__number">2</span>]</span></code><br/><code><span leaf=""> <span class="code-snippet__comment">/*</span></span></code><br/><code><span leaf="">  * At this point:</span></code><br/><code><span leaf="">  * vmp_cs_validated |= validated (set if a code signature exists)</span></code><br/><code><span leaf="">  * vmp_cs_tainted |= tainted (set if code signature violation)</span></code><br/><code><span leaf="">  * vmp_cs_nx |= nx;  ??</span></code><br/><code><span leaf="">  *</span></code><br/><code><span leaf="">  * if vmp_pmapped then have to pmap_disconnect..</span></code><br/><code><span leaf="">  * other flags to check on object or page?</span></code><br/><code><span leaf="">  */</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (page-&gt;vmp_cs_tainted != VMP_CS_ALL_FALSE) {                            [<span class="code-snippet__number">3</span>]</span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">if</span></span><span class="code-snippet__meta"> DEBUG || DEVELOPMENT</span></span></code><br/><code><span leaf=""> <span class="code-snippet__comment">/*</span></span></code><br/><code><span leaf="">  * On development builds, a boot-arg can be used to cause</span></code><br/><code><span leaf="">  * a panic, instead of a quiet repair.</span></code><br/><code><span leaf="">  */</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (vmtc_panic_instead) {</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">panic</span>(<span class="code-snippet__string">&#34;Text page corruption detected: vm_page_t 0x%llx&#34;</span>, (<span class="code-snippet__type">long</span> <span class="code-snippet__type">long</span>)(<span class="code-snippet__type">uintptr_t</span>)page);</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">endif</span></span><span class="code-snippet__meta"><span class="code-snippet__comment">/* DEBUG || DEVELOPMENT */</span></span></span></code><br/><code><span leaf=""> <span class="code-snippet__comment">/*</span></span></code><br/><code><span leaf="">  * We&#39;re going to invalidate this page. Grab a copy of it for comparison.</span></code><br/><code><span leaf="">  */</span></code><br/><code><span leaf=""> ca_event = <span class="code-snippet__built_in">CA_EVENT_ALLOCATE</span>(vmtc_telemetry);</span></code><br/><code><span leaf=""> event = ca_event-&gt;data;</span></code><br/><code><span leaf=""> diagnose_buffer = <span class="code-snippet__built_in">vmtc_text_page_diagnose_setup</span>(code_addr, page, event);</span></code><br/><code><span leaf=""> <span class="code-snippet__comment">/*</span></span></code><br/><code><span leaf="">  * Invalidate, i.e. toss, the corrupted page.</span></code><br/><code><span leaf="">  */</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (!page-&gt;vmp_cleaning &amp;&amp;</span></code><br/><code><span leaf="">     !page-&gt;vmp_laundry &amp;&amp;</span></code><br/><code><span leaf="">     !page-&gt;vmp_fictitious &amp;&amp;</span></code><br/><code><span leaf="">     !page-&gt;vmp_precious &amp;&amp;</span></code><br/><code><span leaf="">     !page-&gt;vmp_absent &amp;&amp;</span></code><br/><code><span leaf="">     !page-&gt;vmp_error &amp;&amp;</span></code><br/><code><span leaf="">     !page-&gt;vmp_dirty &amp;&amp;</span></code><br/><code><span leaf="">     !<span class="code-snippet__built_in">is_page_wired</span>(page)) {</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (page-&gt;vmp_pmapped) {</span></code><br/><code><span leaf=""> <span class="code-snippet__type">int</span> refmod = <span class="code-snippet__built_in">pmap_disconnect</span>(<span class="code-snippet__built_in">VM_PAGE_GET_PHYS_PAGE</span>(page));</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (refmod &amp; VM_MEM_MODIFIED) {</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">SET_PAGE_DIRTY</span>(page, FALSE);</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (refmod &amp; VM_MEM_REFERENCED) {</span></code><br/><code><span leaf=""> page-&gt;vmp_reference = TRUE;</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> <span class="code-snippet__comment">/* If the page seems intentionally modified, don&#39;t trash it. */</span></span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (!page-&gt;vmp_dirty) {</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">VM_PAGE_FREE</span>(page);</span></code><br/><code><span leaf=""> } <span class="code-snippet__keyword">else</span> {</span></code><br/><code><span leaf=""> event-&gt;vmtc_not_eligible = <span class="code-snippet__literal">true</span>;</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> } <span class="code-snippet__keyword">else</span> {</span></code><br/><code><span leaf=""> event-&gt;vmtc_not_eligible = <span class="code-snippet__literal">true</span>;</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">vm_object_unlock</span>(object);</span></code><br/><code><span leaf=""> object = VM_OBJECT_NULL;</span></code><br/><code><span leaf=""> <span class="code-snippet__comment">/*</span></span></code><br/><code><span leaf="">  * Now try to diagnose the type of failure by faulting</span></code><br/><code><span leaf="">  * in a new copy and diff&#39;ing it with what we saved.</span></code><br/><code><span leaf="">  */</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (diagnose_buffer != <span class="code-snippet__literal">NULL</span>) {</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">vmtc_text_page_diagnose</span>(code_addr, diagnose_buffer, event);</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">if</span></span><span class="code-snippet__meta"> DEBUG || DEVELOPMENT</span></span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (corruption_test_va != <span class="code-snippet__number">0</span>) {</span></code><br/><code><span leaf=""> corruption_test_va = <span class="code-snippet__number">0</span>;</span></code><br/><code><span leaf=""> event-&gt;vmtc_testing = <span class="code-snippet__literal">true</span>;</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">endif</span></span><span class="code-snippet__meta"><span class="code-snippet__comment">/* DEBUG || DEVELOPMENT */</span></span></span></code><br/><code><span leaf="">          <span class="code-snippet__built_in">kernel_triage_record</span>(<span class="code-snippet__built_in">thread_tid</span>(<span class="code-snippet__built_in">current_thread</span>()),</span></code><br/><code><span leaf="">     <span class="code-snippet__built_in">KDBG_TRIAGE_EVENTID</span>(KDBG_TRIAGE_SUBSYS_VM, KDBG_TRIAGE_RESERVED, KDBG_TRIAGE_VM_TEXT_CORRUPTION),</span></code><br/><code><span leaf="">     <span class="code-snippet__number">0</span> <span class="code-snippet__comment">/* arg */</span>);</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">CA_EVENT_SEND</span>(ca_event);</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">printf</span>(<span class="code-snippet__string">&#34;Text page corruption detected for pid %d\n&#34;</span>, <span class="code-snippet__built_in">proc_selfpid</span>());</span></code><br/><code><span leaf=""> ++vmtc_total;</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">return</span> KERN_FAILURE;</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf="">done:</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> (object != <span class="code-snippet__literal">NULL</span>) {</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">vm_object_unlock</span>(object);</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">return</span> KERN_SUCCESS;</span></code><br/><code><span leaf="">}</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">  在</span></span><span lang="EN-US"><span leaf="">[1]</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">处获取</span></span><span lang="EN-US"><span leaf="">addr</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">对应的</span></span><span lang="EN-US"><span leaf="">object</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">和</span></span><span lang="EN-US"><span leaf="">page</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">信息，在</span></span><span lang="EN-US"><span leaf="">[2]</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">处调用</span></span><span lang="EN-US"><span leaf="">vm_page_map_and_validate_cs</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">来对这个</span></span><span lang="EN-US"><span leaf="">page</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">进行签名验证，在</span></span><span lang="EN-US"><span leaf="">[3]</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">处如果检测到签名失败，还要进行详细的信息获取，比如要对比这个</span></span><span lang="EN-US"><span leaf="">page</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">是哪一块内存出现了问题。</span></span></p><h2><span style="mso-bookmark:_Toc3;"><span lang="ZH" style="font-family:黑体;mso-ascii-font-family:
Arial;mso-hansi-font-family:Arial;mso-fareast-language:ZH;"><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">3.2 AMFI处理流程</span></span></span></span></h2><p style=""><span lang="EN-US"><span leaf="">    Amfi(Apple Mobile File Integrity)</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">是一个内核扩展，</span></span><span lang="EN-US"><span leaf=""> IOS</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">的代码验签的过程都集中在这个模块中，本文以</span></span><span lang="EN-US"><span leaf="">ios14</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">为例来剖析</span></span><span lang="EN-US"><span leaf="">ios</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">的代码验签过程。</span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf=""><span textstyle="" style="font-size: 18px;font-weight: bold;">3.2.1 vnode_check_signature</span></span></span></p><p style=""><span lang="EN-US"><span leaf="">    MAC</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">系统通过以下代码进入到</span></span><span lang="EN-US"><span leaf="">amfi</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">流程中：</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf=""><span class="code-snippet__function"><span class="code-snippet__type">int</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__title">mac_vnode_check_signature</span><span class="code-snippet__params">(</span><span class="code-snippet__params"><span class="code-snippet__keyword">struct</span></span><span class="code-snippet__params"> vnode *vp, </span><span class="code-snippet__params"><span class="code-snippet__keyword">struct</span></span><span class="code-snippet__params"> cs_blob *cs_blob,</span></span></code><br/><code><span leaf=""><span class="code-snippet__keyword">struct</span> image_params *imgp,</span></code><br/><code><span leaf=""><span class="code-snippet__type">unsigned</span> <span class="code-snippet__type">int</span> *cs_flags, <span class="code-snippet__type">unsigned</span> <span class="code-snippet__type">int</span> *signer_type,</span></code><br/><code><span leaf=""><span class="code-snippet__type">int</span> flags, <span class="code-snippet__type">unsigned</span> <span class="code-snippet__type">int</span> platform) {</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">MAC_CHECK</span>(vnode_check_signature, vp, vp-&gt;v_label, cpu_type, cs_blob,</span></code><br/><code><span leaf="">     cs_flags, signer_type, flags, platform, &amp;fatal_failure_desc, &amp;fatal_failure_desc_len);</span></code><br/><code><span leaf="">}</span></code><br/></pre></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="python"><code><span leaf="">__ZL22_vnode_check_signatureP5vnodeP5labeliP7cs_blobPjS5_ijPPcPm</span></code><br/><code><span leaf="">MOV W0, <span class="code-snippet__comment">#1048 ; size</span></span></code><br/><code><span leaf="">BL _IOMalloc_external</span></code><br/><code><span leaf="">CBZ X0, loc_FFFFFFF008308F44</span></code><br/><code><span leaf="">MOV X22, X0 ; unkown_struct;</span></code><br/><code><span leaf="">LDP X25, X26, [X29,<span class="code-snippet__comment">#arg_0]</span></span></code><br/><code><span leaf="">ADD X0, X0, <span class="code-snippet__comment">#8 ; __dst</span></span></code><br/><code><span leaf="">MOV X27, X22</span></code><br/><code><span leaf="">MOVK X27, <span class="code-snippet__comment">#0x6712,LSL#48</span></span></code><br/><code><span leaf="">ADRL X8, off_FFFFFFF0077AE4F0</span></code><br/><code><span leaf="">PACDA X8, X27</span></code><br/><code><span leaf="">STR X8, [X22] ; *(unkown_struct + <span class="code-snippet__number">0</span>) = pacda()</span></code><br/><code><span leaf="">ADRL X1, l_.<span class="code-snippet__built_in">str</span><span class="code-snippet__number">.82</span> ; __src</span></code><br/><code><span leaf="">MOV W2, <span class="code-snippet__comment">#1024 ; __n</span></span></code><br/><code><span leaf="">BL _memmove ; memmove(unkown_struct + <span class="code-snippet__number">8</span>， src, <span class="code-snippet__number">1024</span>);</span></code><br/><code><span leaf="">STRB WZR, [X22,<span class="code-snippet__comment">#1032] ; *(unkown_struct + 1032) = 0</span></span></code><br/><code><span leaf="">ADRL X8, off_FFFFFFF0077AE4C0</span></code><br/><code><span leaf="">PACDA X8, X27</span></code><br/><code><span leaf="">STR X8, [X22]</span></code><br/><code><span leaf="">STR X24, [X22,<span class="code-snippet__comment">#1040] ; *(unkown_struct + 1040) = vnode</span></span></code><br/><code><span leaf="">MOV X0, X22</span></code><br/><code><span leaf="">MOV X1, X23</span></code><br/><code><span leaf="">MOV X2, X21</span></code><br/><code><span leaf="">MOV X3, X20</span></code><br/><code><span leaf="">MOV X4, X19</span></code><br/><code><span leaf="">MOV W5, <span class="code-snippet__comment">#0</span></span></code><br/><code><span leaf="">MOV X6, X25</span></code><br/><code><span leaf="">MOV X7, X26 ; (unkown_struct, csblob, cs_flags, signer_type, flags, <span class="code-snippet__number">0</span>, *addr1, *addr2)</span></code><br/><code><span leaf="">BL__ZN20StaticPlatformPolicyILb1ELb1ELb0ELb0ELb0ELb0ELb1ELb1ELb0ELb1ELb0ELb0ELb0ELb0ELb1ELb1ELj2ELb1ELb0EE15check_signatureEP8LazyPathiP7cs_blobPjS5_ibbPPcPm</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    进一步调用</span></span><span lang="EN-US"><span leaf="">check_signature</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">函数，从上面的代码中，我们可以推测它的参数结构为：</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="apache"><code><span leaf=""><span class="code-snippet__attribute">check_signature</span>(unkown_struct, csblob, cs_flags, signer_type, flags, <span class="code-snippet__number">0</span>, *addr1, *addr2)。</span></code></pre></p><p><span lang="EN-US"><span leaf=""><span textstyle="" style="font-size: 18px;font-weight: bold;">3.2.2 check_signature</span></span></span></p><h4><span lang="EN-US"><span leaf=""><span textstyle="" style="font-weight: bold;">3.2.2.1 cd hash</span></span></span><span style="font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;"><span leaf=""><span textstyle="" style="font-weight: bold;">在</span></span></span><span lang="EN-US"><span leaf=""><span textstyle="" style="font-weight: bold;">trustcache</span></span></span><span style="font-family:黑体;mso-ascii-font-family:
Arial;mso-hansi-font-family:Arial;"><span leaf=""><span textstyle="" style="font-weight: bold;">里</span></span></span></h4><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf=""><span class="code-snippet__comment">// (unkown_struct, csblob, cs_flags, signer_type, flags, 0, *addr1, *addr2)</span></span></code><br/><code><span leaf="">__int64 __fastcall StaticPlatformPolicy&lt;<span class="code-snippet__literal">true</span>,<span class="code-snippet__literal">true</span>,<span class="code-snippet__literal">false</span>,<span class="code-snippet__literal">false</span>,<span class="code-snippet__literal">false</span>,<span class="code-snippet__literal">false</span>,<span class="code-snippet__literal">true</span>,<span class="code-snippet__literal">true</span>,<span class="code-snippet__literal">false</span>,<span class="code-snippet__literal">true</span>,<span class="code-snippet__literal">false</span>,<span class="code-snippet__literal">false</span>,<span class="code-snippet__literal">false</span>,<span class="code-snippet__literal">false</span>,<span class="code-snippet__literal">true</span>,<span class="code-snippet__literal">true</span>,<span class="code-snippet__number">2u</span>,<span class="code-snippet__literal">true</span>,<span class="code-snippet__literal">false</span>&gt;::<span class="code-snippet__built_in">check_signature</span>(</span></code><br/><code><span leaf="">LazyPath *a1,</span></code><br/><code><span leaf="">__int64 a2,</span></code><br/><code><span leaf=""><span class="code-snippet__type">unsigned</span> <span class="code-snippet__type">int</span> *a3,</span></code><br/><code><span leaf="">_DWORD *a4,</span></code><br/><code><span leaf=""><span class="code-snippet__type">unsigned</span> <span class="code-snippet__type">int</span> a5,</span></code><br/><code><span leaf="">__int64 a6,</span></code><br/><code><span leaf=""><span class="code-snippet__type">char</span> **a7,</span></code><br/><code><span leaf=""><span class="code-snippet__type">unsigned</span> __int64 *a8)</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> ( (StaticPlatformPolicy&lt;<span class="code-snippet__literal">true</span>,<span class="code-snippet__literal">true</span>,<span class="code-snippet__literal">false</span>,<span class="code-snippet__literal">false</span>,<span class="code-snippet__literal">false</span>,<span class="code-snippet__literal">false</span>,<span class="code-snippet__literal">true</span>,<span class="code-snippet__literal">true</span>,<span class="code-snippet__literal">false</span>,<span class="code-snippet__literal">true</span>,<span class="code-snippet__literal">false</span>,<span class="code-snippet__literal">false</span>,<span class="code-snippet__literal">false</span>,<span class="code-snippet__literal">false</span>,<span class="code-snippet__literal">true</span>,<span class="code-snippet__literal">true</span>,<span class="code-snippet__number">2u</span>,<span class="code-snippet__literal">true</span>,<span class="code-snippet__literal">false</span>&gt;::<span class="code-snippet__built_in">loadEntitlementsFromSignature</span>(</span></code><br/><code><span leaf="">&amp;inColl,</span></code><br/><code><span leaf="">a2,</span></code><br/><code><span leaf="">&amp;v114) &amp; <span class="code-snippet__number">1</span>) == <span class="code-snippet__number">0</span> )</span></code><br/><code><span leaf=""> {</span></code><br/><code><span leaf="">v30 = <span class="code-snippet__built_in">fatal_error_fmt</span>(</span></code><br/><code><span leaf="">a1,</span></code><br/><code><span leaf="">a7,</span></code><br/><code><span leaf="">a8,</span></code><br/><code><span leaf=""><span class="code-snippet__string">&#34;The signature could not be validated because AMFI could not load its entitlements for validation: %s&#34;</span>,</span></code><br/><code><span leaf="">v114);</span></code><br/><code><span leaf="">v31 = <span class="code-snippet__number">0LL</span>;</span></code><br/><code><span leaf="">v32 = <span class="code-snippet__number">1LL</span>;</span></code><br/><code><span leaf="">v16 = inColl;</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">if</span> ( !inColl )</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">goto</span> LABEL_20;</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">goto</span> LABEL_19;</span></code><br/><code><span leaf=""> }</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    loadEntitlementsFromSignature</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">函数的作用是从</span></span><span lang="EN-US"><span leaf="">struct cs_blob</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">中获取进程的</span></span><span lang="EN-US"><span leaf="">entitlements</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">，它的大小在</span></span><span lang="EN-US"><span leaf="">8byte</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">到</span></span><span lang="EN-US"><span leaf="">128m</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">之间。如果</span></span><span lang="EN-US"><span leaf="">cs_blob</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">存储的</span></span><span lang="EN-US"><span leaf="">cd hash</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">在</span></span><span lang="EN-US"><span leaf="">static trustcache</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">或</span></span><span lang="EN-US"><span leaf="">loaded trustcache</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">中，那么会在</span></span><span lang="EN-US"><span leaf="">entitlements</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">中加入一个新节点</span></span><span lang="EN-US"><span leaf="">platform-application</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">如果</span></span><span lang="EN-US"><span leaf="">cs_blob</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">存取的</span></span><span lang="EN-US"><span leaf="">identifier</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">为空，则在</span></span><span lang="EN-US"><span leaf="">entitlements</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">中删除节点</span></span><span lang="EN-US"><span leaf="">com.apple.private.signing-identifier</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，否则设置为</span></span><span lang="EN-US"><span leaf="">cs_blob</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">对应的</span></span><span lang="EN-US"><span leaf="">identifier</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf="">...</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">if</span> ( v23 &amp;&amp; (v24 = (<span class="code-snippet__type">const</span> <span class="code-snippet__type">char</span> *)((__int64 (*)(<span class="code-snippet__type">void</span>))v23-&gt;__vftable[<span class="code-snippet__number">1</span>].isEqualTo)()) != <span class="code-snippet__number">0LL</span> )</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf="">v25 = (OSDictionary *)v24;</span></code><br/><code><span leaf="">*a3 |= <span class="code-snippet__number">0x200u</span>;                     <span class="code-snippet__comment">// cs_flags |= CS_KILL</span></span></code><br/><code><span leaf=""><span class="code-snippet__keyword">if</span> ( !<span class="code-snippet__built_in">strcmp</span>(v24, <span class="code-snippet__string">&#34;get-task-allow&#34;</span>) )</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">LOBYTE</span>(v126[<span class="code-snippet__number">0</span>]) = <span class="code-snippet__number">0</span>;</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> ( !(<span class="code-snippet__type">unsigned</span> <span class="code-snippet__type">int</span>)AppleMobileFileIntegrity::<span class="code-snippet__built_in">AMFIEntitlementGetBool</span>(</span></code><br/><code><span leaf="">(AppleMobileFileIntegrity *)v16,</span></code><br/><code><span leaf=""> v25,</span></code><br/><code><span leaf=""> (<span class="code-snippet__type">const</span> <span class="code-snippet__type">char</span> *)v126,</span></code><br/><code><span leaf=""> v26)</span></code><br/><code><span leaf=""> &amp;&amp; <span class="code-snippet__built_in">LOBYTE</span>(v126[<span class="code-snippet__number">0</span>]) != <span class="code-snippet__number">0</span> )</span></code><br/><code><span leaf=""> {</span></code><br/><code><span leaf=""> *a3 |= <span class="code-snippet__number">4u</span>;                      <span class="code-snippet__comment">// CS_GET_TASK_ALLOW</span></span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf="">}</span></code><br/><code><span leaf="">}</span></code><br/><code><span leaf="">...</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    获取</span></span><span lang="EN-US"><span leaf="">entitlements</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">后，</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">首先将第三个参数</span></span><span lang="EN-US"><span leaf="">cs_flags</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">加上</span></span><span lang="EN-US"><span leaf="">CS_KILL</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">标志。如果</span></span><span lang="EN-US"><span leaf="">entitlements</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">包含</span></span><span lang="EN-US"><span leaf="">get-task-allow</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">节点，则再把</span></span><span lang="EN-US"><span leaf="">CS_GET_TASK_ALLOW</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">标志加入到</span></span><span lang="EN-US"><span leaf="">cs_flags</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">中。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="nginx"><code><span leaf=""> <span class="code-snippet__attribute">cdhash</span> = (const unsigned __int8 *)csblob_get_cdhash(v13);</span></code><br/><code><span leaf=""> <span class="code-snippet__attribute">if</span> ( !cdhash )</span></code><br/><code><span leaf=""> {</span></code><br/><code><span leaf=""> <span class="code-snippet__attribute">v30</span> = fatal_error_fmt(a1, a7, a8, <span class="code-snippet__string">&#34;Internal Error: No cdhash found.&#34;</span>);</span></code><br/><code><span leaf=""> <span class="code-snippet__attribute">goto</span> LABEL_37;</span></code><br/><code><span leaf=""> }</span></code><br/></pre></p><p style=""><span lang="EN-US"><span leaf="">    接着获取进程的</span></span><span lang="EN-US"><span leaf="">cd hash</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，如果不存在直接返回。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf=""><span class="code-snippet__keyword">if</span> ( (<span class="code-snippet__built_in">AMFIIsCodeDirectoryInTrustCache</span>(cdhash) &amp; <span class="code-snippet__number">1</span>) == <span class="code-snippet__number">0</span> &amp;&amp; !(<span class="code-snippet__type">unsigned</span> <span class="code-snippet__type">int</span>)<span class="code-snippet__built_in">codeDirectoryHashIsInLoadedTrustCache</span>(v37) )</span></code><br/><code><span leaf=""> {</span></code><br/><code><span leaf="">}</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    如果</span></span><span lang="EN-US"><span leaf="">cd hash</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">在</span></span><span lang="EN-US"><span leaf="">static trustcache</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">或</span></span><span lang="EN-US"><span leaf="">loaded trustcache</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">里。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="makefile"><code><span leaf=""> v39 = postValidation(a1, v13, v38, <span class="code-snippet__string">&#34;in-kernel&#34;</span>, a7, a8);</span></code><br/><code><span leaf=""> v30 = IsCDHashBlacklisted(v37);</span></code><br/><code><span leaf=""> if ( (_DWORD)v30 )</span></code><br/><code><span leaf=""> {</span></code><br/><code><span leaf="">v30 = fatal_error_fmt(a1, a7, a8, <span class="code-snippet__string">&#34;Bad things happened.&#34;</span>);</span></code><br/><code><span leaf=""><span class="code-snippet__section">LABEL_37:</span></span></code><br/><code><span leaf="">v31 = 0LL;</span></code><br/><code><span leaf="">goto LABEL_82;</span></code><br/><code><span leaf=""> }</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    postValidation</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">函数判断</span></span><span lang="EN-US"><span leaf="">cs_flags</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">是否包含</span></span><span lang="EN-US"><span leaf="">CS_PLATFORM_BINARY</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，如果是返回</span></span><span lang="EN-US"><span leaf="">1</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。否则继续判断</span></span><span lang="EN-US"><span leaf="">hash type</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">是否为</span></span><span lang="EN-US"><span leaf="">sha256</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，如果是返回</span></span><span lang="EN-US"><span leaf="">1</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，其余返回</span></span><span lang="EN-US"><span leaf="">0</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。</span></span></p><p style=""><span lang="EN-US"><span leaf="">    Ios</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">还为</span></span><span lang="EN-US"><span leaf="">cd hash</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">设置了一个黑名单，</span></span><span lang="EN-US"><span leaf="">IsCDHashBlacklisted</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">函数判断一个</span></span><span lang="EN-US"><span leaf="">cd hash</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">是否在黑名单中。</span></span></p><p style=""><span lang="EN-US"><span leaf="">*a3 |= 0x20000000u;</span><span leaf="">// CS_SIGNED</span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">    最后将</span></span><span lang="EN-US"><span leaf="">CS_SIGNED</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">标志放入到</span></span><span lang="EN-US"><span leaf="">cs_flags</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">中，函数返回。</span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">    我们看到如果一个</span></span><span lang="EN-US"><span leaf="">cd hash</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">在</span></span><span lang="EN-US"><span leaf="">static trustcache</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">或者在</span></span><span lang="EN-US"><span leaf="">loaded trustcache</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">里，则直接完成此次判断，接下来继续分析不在</span></span><span lang="EN-US"><span leaf="">trustcache</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">里的情况。</span></span></p><h4><span lang="EN-US"><span leaf=""><span textstyle="" style="font-weight: bold;">3.2.2.2 cd hash</span></span></span><span style="font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;"><span leaf=""><span textstyle="" style="font-weight: bold;">不在</span></span></span><span lang="EN-US"><span leaf=""><span textstyle="" style="font-weight: bold;">trustcache</span></span></span><span style="font-family:黑体;mso-ascii-font-family:
Arial;mso-hansi-font-family:Arial;"><span leaf=""><span textstyle="" style="font-weight: bold;">里</span></span></span></h4><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf=""><span class="code-snippet__keyword">if</span> ( _codeDirectoryHashInCompilationServiceHash(v37) &amp;&amp; (<span class="code-snippet__type">unsigned</span> <span class="code-snippet__type">int</span>)<span class="code-snippet__built_in">noEntitlementsPresent</span>(v13) )</span></code><br/><code><span leaf=""> {</span></code><br/><code><span leaf=""><span class="code-snippet__built_in">LOBYTE</span>(v126[<span class="code-snippet__number">0</span>]) = <span class="code-snippet__number">0</span>;</span></code><br/><code><span leaf="">v41 = <span class="code-snippet__built_in">current_proc</span>();</span></code><br/><code><span leaf="">AppleMobileFileIntegrity::<span class="code-snippet__built_in">AMFIEntitlementGetBool</span>(</span></code><br/><code><span leaf="">v41,</span></code><br/><code><span leaf="">(proc *)<span class="code-snippet__string">&#34;com.apple.private.amfi.can-execute-cdhash&#34;</span>,</span></code><br/><code><span leaf="">(<span class="code-snippet__type">const</span> <span class="code-snippet__type">char</span> *)v126,</span></code><br/><code><span leaf="">v42);</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">if</span> ( <span class="code-snippet__built_in">LOBYTE</span>(v126[<span class="code-snippet__number">0</span>]) )</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf="">v30 = <span class="code-snippet__built_in">postValidation</span>(a1, v13, *a3, <span class="code-snippet__string">&#34;can-execute-cdhash&#34;</span>, a7, a8);</span></code><br/><code><span leaf="">v40 = v30 ^ <span class="code-snippet__number">1</span>;                         <span class="code-snippet__comment">// 非(platform binary并且hash type为sha256)</span></span></code><br/><code><span leaf="">}</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">else</span></span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""><span class="code-snippet__built_in">IOLog</span>(<span class="code-snippet__string">&#34;AMFI: can-execute-cdhash code in non-entitled context.\n&#34;</span>);</span></code><br/><code><span leaf="">v40 = <span class="code-snippet__number">1</span>;</span></code><br/><code><span leaf="">}</span></code><br/><code><span leaf="">v31 = <span class="code-snippet__number">0LL</span>;</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">goto</span> LABEL_81;</span></code><br/><code><span leaf="">}</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    首先判断这个</span></span><span lang="EN-US"><span leaf="">cd hash</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">如果在</span></span><span lang="EN-US"><span leaf="">compilationServiceHash</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">里，并且进程所含的</span></span><span lang="EN-US"><span leaf="">entitlements</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">不为空，如果进程的</span></span><span lang="EN-US"><span leaf="">entitlements</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">包含</span></span><span lang="EN-US"><span leaf="">com.apple.private.amfi.can-execute-cdhash</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">，并且这个进程并非</span></span><span lang="EN-US"><span leaf="">platform binary</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">，则完成此次判断直接返回。</span></span><span lang="EN-US"><span leaf="">compilationServiceHash</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">由用户态进程调用</span></span><span lang="EN-US"><span leaf="">AMFI loadCompilationServiceCodeDirectoryHash</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">接口进行设置，请参考</span></span><span lang="EN-US"><span leaf="">3.3</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">节。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="perl"><code><span leaf="">addr = (unsigned <span class="code-snippet__keyword">int</span> *)csblob_get_addr(<span class="code-snippet__number">v112</span>);</span></code><br/><code><span leaf=""> size = csblob_get_size(<span class="code-snippet__number">v112</span>);</span></code><br/><code><span leaf=""> blob_bytes = csblob_find_blob_bytes(addr, size, <span class="code-snippet__number">0</span>, <span class="code-snippet__number">0xFADE0C02</span>);<span class="code-snippet__regexp">//</span> CSMAGIC_CODEDIRECTORY</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> ( !blob_bytes )</span></code><br/><code><span leaf=""> {</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">printf</span>(<span class="code-snippet__string">&#34;AMFI: &#39;</span><span class="code-snippet__string"><span class="code-snippet__variable">%s</span></span><span class="code-snippet__string">&#39; has no cd?\n&#34;</span>, <span class="code-snippet__number">v48</span>);</span></code><br/><code><span leaf=""> <span class="code-snippet__number">v123</span>[<span class="code-snippet__number">1</span>] = 0LL;</span></code><br/><code><span leaf="">LABEL_63:</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">printf</span>(<span class="code-snippet__string">&#34;AMFI: &#39;</span><span class="code-snippet__string"><span class="code-snippet__variable">%s</span></span><span class="code-snippet__string">&#39;: Unrecoverable CT signature issue, bailing out.\n&#34;</span>);</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">goto</span> LABEL_79;</span></code><br/><code><span leaf=""> }</span></code><br/></pre></p><p style=""><span lang="EN-US"><span leaf="">    接着搜索</span></span><span lang="EN-US"><span leaf="">cs_blob</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">结构是否包含</span></span><span lang="EN-US"><span leaf="">CSMAGIC_CODEDIRECTORY</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，如果不存在则直接返回。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="perl"><code><span leaf=""> <span class="code-snippet__number">v52</span> = (__int64)blob_bytes;</span></code><br/><code><span leaf=""> <span class="code-snippet__number">v108</span> = a1;</span></code><br/><code><span leaf=""> <span class="code-snippet__number">v53</span> = bswap32(blob_bytes[<span class="code-snippet__number">1</span>]);               <span class="code-snippet__regexp">//</span> CS_GenericBlob.length</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> ( <span class="code-snippet__number">v53</span> &lt;= <span class="code-snippet__number">7</span> )</span></code><br/><code><span leaf=""> {</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">printf</span>(<span class="code-snippet__string">&#34;AMFI: &#39;</span><span class="code-snippet__string"><span class="code-snippet__variable">%s</span></span><span class="code-snippet__string">&#39; has short cd (</span><span class="code-snippet__string"><span class="code-snippet__variable">%u</span></span><span class="code-snippet__string">)?\n&#34;</span>);</span></code><br/><code><span leaf="">LABEL_62:</span></code><br/><code><span leaf=""> <span class="code-snippet__number">v123</span>[<span class="code-snippet__number">1</span>] = 0LL;</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">goto</span> LABEL_63;</span></code><br/><code><span leaf=""> }</span></code><br/></pre></p><p style=""><span lang="EN-US"><span leaf="">    CODEDIRECTORY</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">结构不能小于</span></span><span lang="EN-US"><span leaf="">7</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf="">v54 = (<span class="code-snippet__type">unsigned</span> <span class="code-snippet__type">int</span> *)<span class="code-snippet__built_in">csblob_get_addr</span>(v112);</span></code><br/><code><span leaf="">v55 = <span class="code-snippet__built_in">csblob_get_size</span>(v112);</span></code><br/><code><span leaf="">v56 = <span class="code-snippet__built_in">csblob_find_blob_bytes</span>(v54, v55, <span class="code-snippet__number">0x10000</span>, <span class="code-snippet__number">0xFADE0B01</span>);<span class="code-snippet__comment">// CSMAGIC_BLOBWRAPPER  CMS Signature</span></span></code><br/><code><span leaf=""><span class="code-snippet__keyword">if</span> ( !v56 )</span></code><br/><code><span leaf=""> {</span></code><br/><code><span leaf=""><span class="code-snippet__built_in">printf</span>(<span class="code-snippet__string">&#34;AMFI: &#39;%s&#39; has no CMS blob?\n&#34;</span>);</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">goto</span> LABEL_62;</span></code><br/><code><span leaf="">}</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    继续搜索</span></span><span lang="EN-US"><span leaf="">cs_blob</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">是否包含</span></span><span lang="EN-US"><span leaf="">CSMAGIC_BLOBWRAPPER</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，它会携带证书信息。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="perl"><code><span leaf=""> <span class="code-snippet__keyword">if</span> ( <span class="code-snippet__number">v58</span> &lt;= <span class="code-snippet__number">7</span> )                             // CS_GenericBlob.length</span></code><br/><code><span leaf=""> {</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">printf</span>(<span class="code-snippet__string">&#34;AMFI: &#39;</span><span class="code-snippet__string"><span class="code-snippet__variable">%s</span></span><span class="code-snippet__string">&#39; has short cms (</span><span class="code-snippet__string"><span class="code-snippet__variable">%u</span></span><span class="code-snippet__string">), bailing out.\n&#34;</span>);</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">goto</span> LABEL_62;</span></code><br/><code><span leaf=""> }</span></code><br/></pre></p><p style=""><span lang="EN-US"><span leaf="">    Cms</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">结构不能小于</span></span><span lang="EN-US"><span leaf="">7</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf=""> <span class="code-snippet__keyword">if</span> ( v57 == <span class="code-snippet__number">0x8000000</span> )                     <span class="code-snippet__comment">// CS_GenericBlob.length == 0</span></span></code><br/><code><span leaf=""> {</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> ( (<span class="code-snippet__type">unsigned</span> <span class="code-snippet__type">int</span>)<span class="code-snippet__built_in">CTEvaluateAMFICodeSignatureCMS</span>(</span></code><br/><code><span leaf=""> v59,</span></code><br/><code><span leaf=""> v100,</span></code><br/><code><span leaf=""> v52,</span></code><br/><code><span leaf=""> v53,</span></code><br/><code><span leaf=""> v60,</span></code><br/><code><span leaf=""> <span class="code-snippet__number">0LL</span>,</span></code><br/><code><span leaf=""> <span class="code-snippet__number">0LL</span>,</span></code><br/><code><span leaf=""> (__int64 *)&amp;v123[<span class="code-snippet__number">1</span>],</span></code><br/><code><span leaf=""> &amp;v117,</span></code><br/><code><span leaf=""> &amp;v116,</span></code><br/><code><span leaf=""> v123,</span></code><br/><code><span leaf=""> (__int64)&amp;v122) )</span></code><br/><code><span leaf=""> {</span></code><br/><code><span leaf=""> v123[<span class="code-snippet__number">1</span>] = <span class="code-snippet__number">0LL</span>;</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">printf</span>(<span class="code-snippet__string">&#34;AMFI: &#39;%s&#39; does not pass CT evaluation, result: %#x\n&#34;</span>);</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">goto</span> LABEL_63;</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf="">}</span></code><br/></pre></p><p style=""><span lang="EN-US"><span leaf="">    CTEvaluateAMFICodeSignatureCMS</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">函数验证</span></span><span lang="EN-US"><span leaf="">cms</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">携带的证书是否由苹果公司签发。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="perl"><code><span leaf=""><span class="code-snippet__keyword">if</span> ( (_DWORD)<span class="code-snippet__number">v116</span> )</span></code><br/><code><span leaf=""> {</span></code><br/><code><span leaf="">hashtype = csblob_get_hashtype(<span class="code-snippet__number">v112</span>);</span></code><br/><code><span leaf=""><span class="code-snippet__number">v70</span> = (const unsigned __int8 *)<span class="code-snippet__number">v123</span>[<span class="code-snippet__number">0</span>];</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">if</span> ( (_DWORD)<span class="code-snippet__number">v116</span> == <span class="code-snippet__number">1</span> )</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""><span class="code-snippet__number">v71</span> = <span class="code-snippet__number">1</span>;</span></code><br/><code><span leaf=""><span class="code-snippet__number">v61</span> = <span class="code-snippet__number">v108</span>;</span></code><br/><code><span leaf="">}</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">else</span></span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""><span class="code-snippet__number">v61</span> = <span class="code-snippet__number">v108</span>;</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">if</span> ( (_DWORD)<span class="code-snippet__number">v116</span> != <span class="code-snippet__number">4</span> )</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">printf</span>(<span class="code-snippet__string">&#34;AMFI: &#39;</span><span class="code-snippet__string"><span class="code-snippet__variable">%s</span></span><span class="code-snippet__string">&#39; has unknown CT digest type </span><span class="code-snippet__string"><span class="code-snippet__variable">%#x</span></span><span class="code-snippet__string">\n&#34;</span>);</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">goto</span> LABEL_149;</span></code><br/><code><span leaf="">}</span></code><br/><code><span leaf=""><span class="code-snippet__number">v71</span> = <span class="code-snippet__number">2</span>;</span></code><br/><code><span leaf="">}</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">if</span> ( <span class="code-snippet__number">v71</span> == hashtype )</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">if</span> ( <span class="code-snippet__number">v122</span> &gt; <span class="code-snippet__number">19</span> )</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">if</span> ( !memcmp(<span class="code-snippet__number">v46</span>, <span class="code-snippet__number">v123</span>[<span class="code-snippet__number">0</span>], 0x14uLL) )</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">goto</span> LABEL_70;</span></code><br/><code><span leaf="">*(_QWORD *)&amp;<span class="code-snippet__number">v94</span> = 0xAAAAAAAAAAAAAAAALL;</span></code><br/><code><span leaf="">*((_QWORD *)&amp;<span class="code-snippet__number">v94</span> + <span class="code-snippet__number">1</span>) = 0xAAAAAAAAAAAAAAAALL;</span></code><br/><code><span leaf="">*(_OWORD *)&amp;<span class="code-snippet__number">v125</span>[<span class="code-snippet__number">25</span>] = <span class="code-snippet__number">v94</span>;</span></code><br/><code><span leaf="">*(_OWORD *)<span class="code-snippet__number">v125</span> = <span class="code-snippet__number">v94</span>;</span></code><br/><code><span leaf="">*(_OWORD *)&amp;<span class="code-snippet__number">v125</span>[<span class="code-snippet__number">16</span>] = <span class="code-snippet__number">v94</span>;</span></code><br/><code><span leaf="">*(_OWORD *)&amp;<span class="code-snippet__number">v127</span>[<span class="code-snippet__number">9</span>] = <span class="code-snippet__number">v94</span>;</span></code><br/><code><span leaf="">*(_OWORD *)<span class="code-snippet__number">v126</span> = <span class="code-snippet__number">v94</span>;</span></code><br/><code><span leaf="">*(_OWORD *)<span class="code-snippet__number">v127</span> = <span class="code-snippet__number">v94</span>;</span></code><br/><code><span leaf="">cdhash_to_string(<span class="code-snippet__number">v125</span>, <span class="code-snippet__number">v46</span>);</span></code><br/><code><span leaf="">cdhash_to_string((char *)<span class="code-snippet__number">v126</span>, <span class="code-snippet__number">v70</span>);</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">printf</span>(<span class="code-snippet__string">&#34;AMFI: &#39;</span><span class="code-snippet__string"><span class="code-snippet__variable">%s</span></span><span class="code-snippet__string">&#39;: cdhash mismatch: actual &#39;</span><span class="code-snippet__string"><span class="code-snippet__variable">%s</span></span><span class="code-snippet__string">&#39; != expected &#39;</span><span class="code-snippet__string"><span class="code-snippet__variable">%s</span></span><span class="code-snippet__string">&#39;\n&#34;</span>);</span></code><br/><code><span leaf="">}</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">else</span></span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">printf</span>(<span class="code-snippet__string">&#34;AMFI: &#39;</span><span class="code-snippet__string"><span class="code-snippet__variable">%s</span></span><span class="code-snippet__string">&#39; has unexpected digest data len </span><span class="code-snippet__string"><span class="code-snippet__variable">%zu</span></span><span class="code-snippet__string"> (type </span><span class="code-snippet__string"><span class="code-snippet__variable">%#x</span></span><span class="code-snippet__string">)\n&#34;</span>);</span></code><br/><code><span leaf="">}</span></code><br/><code><span leaf="">}</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">else</span></span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">printf</span>(<span class="code-snippet__string">&#34;AMFI: &#39;</span><span class="code-snippet__string"><span class="code-snippet__variable">%s</span></span><span class="code-snippet__string">&#39; has unexpected digest type, actual </span><span class="code-snippet__string"><span class="code-snippet__variable">%#x</span></span><span class="code-snippet__string"> != expected </span><span class="code-snippet__string"><span class="code-snippet__variable">%#x</span></span><span class="code-snippet__string">\n&#34;</span>);</span></code><br/><code><span leaf="">}</span></code><br/><code><span leaf="">LABEL_149:</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">printf</span>(<span class="code-snippet__string">&#34;AMFI: &#39;</span><span class="code-snippet__string"><span class="code-snippet__variable">%s</span></span><span class="code-snippet__string">&#39;: V2 hash agility validation failed, bailing out.\n&#34;</span>);</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">goto</span> LABEL_63;</span></code><br/><code><span leaf=""> }</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    如果</span></span><span lang="EN-US"><span leaf="">v116</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">不为空，还要判断</span></span><span lang="EN-US"><span leaf="">CTEvaluateAMFICodeSignatureCMS</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">返回的</span></span><span lang="EN-US"><span leaf="">cd hash</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">值是否与当前</span></span><span lang="EN-US"><span leaf="">csblob</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">的</span></span><span lang="EN-US"><span leaf="">cd hash</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">值是否相同，不相同则验证失败返回。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="perl"><code><span leaf="">LABEL_70:</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">if</span> ( ((unsigned __int64)<span class="code-snippet__number">v123</span>[<span class="code-snippet__number">1</span>] &amp; <span class="code-snippet__number">0x1FF80</span>) == <span class="code-snippet__number">0</span> )</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">printf</span>(<span class="code-snippet__string">&#34;AMFI: &#39;</span><span class="code-snippet__string"><span class="code-snippet__variable">%s</span></span><span class="code-snippet__string">&#39;: unsuitable CT policy </span><span class="code-snippet__string"><span class="code-snippet__variable">%#llx</span></span><span class="code-snippet__string"> for this platform/device, rejecting signature.\n&#34;</span>);</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">goto</span> LABEL_79;</span></code><br/><code><span leaf="">}</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    v123[1]</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">是</span></span><span lang="EN-US"><span leaf="">CTEvaluateAMFICodeSignatureCMS</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">返回的某个标志值。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="makefile"><code><span leaf="">if ( ((__int64)v123[1] &amp; 0x5100) != 0 &amp;&amp; allow3rdParty &amp;&amp; !IsCDHashBlacklisted(v46))</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf="">IOLog(<span class="code-snippet__string">&#34;App Store Fast Path -&gt; %s\n&#34;</span>, v48);</span></code><br/><code><span leaf="">v64 = *a3 | 0x4000;                    // CS_ENTITLEMENTS_VALIDATED</span></code><br/><code><span leaf="">*a3 = v64;</span></code><br/><code><span leaf="">v15 = v107;</span></code><br/><code><span leaf="">v65 = v103;</span></code><br/><code><span leaf="">v63 = v105;</span></code><br/><code><span leaf="">goto LABEL_123;</span></code><br/><code><span leaf="">}</span></code><br/><code><span leaf="">*a3 |= 0x20000000u; // CS_SIGNED</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">  0x5100</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">代表</span></span><span lang="EN-US"><span leaf="">app</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">由应用市场签发，对</span></span><span lang="EN-US"><span leaf="">cs_flags</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">标志设置</span></span><span lang="EN-US"><span leaf=""> CS_ENTITLEMENTS_VALIDATED|CS_SIGNED</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，然后直接返回。</span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">   可以看到</span></span><span lang="EN-US"><span leaf="">ios</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">对</span></span><span lang="EN-US"><span leaf="">app</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">应用也可以使能</span></span><span lang="EN-US"><span leaf="">CDHashBlacklisted</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">这样可以将某个</span></span><span lang="EN-US"><span leaf="">app</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">的</span></span><span lang="EN-US"><span leaf="">cd hash</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">加入黑名单，就可以防止它运行。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="makefile"><code><span leaf="">if ( !allow3rdParty)</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""><span class="code-snippet__section">printf(&#34;AMFI: &#39;%s&#39; does not pass kernel-side policy for this model, bailing out.\n&#34;, v48);</span></span></code><br/><code><span leaf="">v62 = 0;</span></code><br/><code><span leaf="">v66 = 0;</span></code><br/><code><span leaf="">v63 = v105;</span></code><br/><code><span leaf=""><span class="code-snippet__section">LABEL_120:</span></span></code><br/><code><span leaf="">if ( !(v66 | v62) )</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf="">if ( v102 &amp;&amp; !v113 )</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""><span class="code-snippet__section">printf(&#34;AMFI: code signature validation failed.\n&#34;);</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">printf(&#34;AMFI: bailing out because of restricted entitlements.\n&#34;);</span></span></code><br/><code><span leaf="">v30 = fatal_error_fmt(</span></code><br/><code><span leaf=""> v61,</span></code><br/><code><span leaf=""> v105,</span></code><br/><code><span leaf=""> v103,</span></code><br/><code><span leaf=""> <span class="code-snippet__string">&#34;Code has restricted entitlements, but the validation of its code signature failed.\n&#34;</span></span></code><br/><code><span leaf=""> <span class="code-snippet__string">&#34;Unsatisfied Entitlements: %s&#34;</span>,</span></code><br/><code><span leaf=""> v31);</span></code><br/><code><span leaf="">goto LABEL_80;</span></code><br/><code><span leaf="">}</span></code><br/><code><span leaf=""><span class="code-snippet__section">LABEL_79:</span></span></code><br/><code><span leaf="">v30 = printf(<span class="code-snippet__string">&#34;AMFI: code signature validation failed.\n&#34;</span>);</span></code><br/><code><span leaf=""><span class="code-snippet__section">LABEL_80:</span></span></code><br/><code><span leaf="">v40 = 1;</span></code><br/><code><span leaf="">v15 = v107;</span></code><br/><code><span leaf="">goto LABEL_81;</span></code><br/><code><span leaf="">}</span></code><br/><code><span leaf="">if ( !v66 )</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf="">v30 = printf(<span class="code-snippet__string">&#34;AMFI: code signature validation failed.\n&#34;</span>);</span></code><br/><code><span leaf="">v15 = v107;</span></code><br/><code><span leaf="">if ( v62 )</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""><span class="code-snippet__section">IOLog(&#34;AMFI: detected an anomaly during entitlement parsing.\n&#34;);</span></span></code><br/><code><span leaf="">v30 = fatal_error_fmt(v61, v63, v103, <span class="code-snippet__string">&#34;anomaly detecting during entitlement parsing\n&#34;</span>);</span></code><br/><code><span leaf="">}</span></code><br/><code><span leaf="">v40 = 1;</span></code><br/><code><span leaf="">goto LABEL_81;</span></code><br/><code><span leaf="">}</span></code><br/><code><span leaf="">v64 = *a3;</span></code><br/><code><span leaf="">v15 = v107;</span></code><br/><code><span leaf="">v65 = v103;</span></code><br/><code><span leaf=""><span class="code-snippet__section">LABEL_123:</span></span></code><br/><code><span leaf="">v30 = postValidation(v61, v112, v64, <span class="code-snippet__string">&#34;dynamic&#34;</span>, v63, v65);</span></code><br/><code><span leaf="">v40 = v30 ^ 1;</span></code><br/><code><span leaf="">goto LABEL_81;</span></code><br/><code><span leaf="">}</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    如果内核配置为不允许加载三方应用，则打印一些出错信息，直接返回。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="perl"><code><span leaf=""><span class="code-snippet__keyword">if</span> ( (csblob_get_flags(<span class="code-snippet__number">v112</span>) &amp; <span class="code-snippet__number">2</span>) == <span class="code-snippet__number">0</span> )  // CS_ADHOC</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">printf</span>(<span class="code-snippet__string">&#34;AMFI: &#39;</span><span class="code-snippet__string"><span class="code-snippet__variable">%s</span></span><span class="code-snippet__string">&#39; has zero length cms, but is not adhoc?\n&#34;</span>);</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">goto</span> LABEL_63;</span></code><br/><code><span leaf="">}</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">printf</span>(<span class="code-snippet__string">&#34;AMFI: &#39;</span><span class="code-snippet__string"><span class="code-snippet__variable">%s</span></span><span class="code-snippet__string">&#39; is adhoc signed.\n&#34;</span>, <span class="code-snippet__number">v48</span>);</span></code><br/><code><span leaf=""><span class="code-snippet__number">v61</span> = <span class="code-snippet__number">v108</span>;</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    如果允许三方应用，则判断</span></span><span lang="EN-US"><span leaf="">cs_flags</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">是否为</span></span><span lang="EN-US"><span leaf="">CS_ADHOC</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，不是的话则直接返回。</span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">   接下来要与用户态进程</span></span><span lang="EN-US"><span leaf="">amfid</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">交互，来判断</span></span><span lang="EN-US"><span leaf="">CS_ADHOC</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">进程是否合法。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="makefile"><code><span leaf="">if ( (unsigned int)getDaemonPort(v123) )</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""><span class="code-snippet__section">IOLog(&#34;StaticPlatformPolicy&lt;%d&gt;: no registered daemon port\n&#34;, 2LL);</span></span></code><br/><code><span leaf="">v62 = 0;</span></code><br/><code><span leaf="">v63 = v105;</span></code><br/><code><span leaf=""><span class="code-snippet__section">LABEL_116:</span></span></code><br/><code><span leaf="">v86 = 0;</span></code><br/><code><span leaf=""><span class="code-snippet__section">LABEL_117:</span></span></code><br/><code><span leaf="">if ( v62 )</span></code><br/><code><span leaf="">v66 = 0;</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">else</span></span></code><br/><code><span leaf="">v66 = v86;</span></code><br/><code><span leaf="">goto LABEL_120;</span></code><br/><code><span leaf="">}</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    获取</span></span><span lang="EN-US"><span leaf="">afmid</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">进程的</span></span><span lang="EN-US"><span leaf="">port</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，</span></span><span lang="EN-US"><span leaf="">mach</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">微内核通过</span></span><span lang="EN-US"><span leaf="">port</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">进行进程间通讯。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="markdown"><code><span leaf="">v91 = verify<span class="code-snippet__emphasis">_code_</span>directory(</span></code><br/><code><span leaf=""> (<span class="code-snippet__strong">__int64)v89,</span></span></code><br/><code><span leaf=""> (__int64)v61 + 8,</span></code><br/><code><span leaf=""> base<span class="code-snippet__emphasis">_offset,</span></span></code><br/><code><span leaf=""> v110,</span></code><br/><code><span leaf=""> v88,</span></code><br/><code><span leaf=""> v113 != 0,</span></code><br/><code><span leaf=""> 2LL,</span></code><br/><code><span leaf=""> v116,</span></code><br/><code><span leaf=""> v117,</span></code><br/><code><span leaf=""> (_DWORD <span class="code-snippet__emphasis">*)&amp;v118 + 1,</span></span></code><br/><code><span leaf=""> &amp;v120,</span></code><br/><code><span leaf=""> &amp;v119,</span></code><br/><code><span leaf=""> v109,</span></code><br/><code><span leaf=""> (_DWORD *)&amp;v121 + 1,</span></code><br/><code><span leaf=""> &amp;v121,</span></code><br/><code><span leaf=""> &amp;v118,</span></code><br/><code><span leaf=""> v31,</span></code><br/><code><span leaf=""> (<span class="code-snippet__strong">__int64)&amp;v123[1],</span></span></code><br/><code><span leaf=""> v126);</span></code><br/></pre></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">  调用</span></span><span lang="EN-US"><span leaf="">verify_code_directory</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">让用户态</span></span><span lang="EN-US"><span leaf="">amfid</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">去做校验。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="perl"><code><span leaf=""> <span class="code-snippet__keyword">if</span> ( <span class="code-snippet__number">v92</span> == -<span class="code-snippet__number">308</span> )</span></code><br/><code><span leaf=""> {</span></code><br/><code><span leaf="">IOLog(<span class="code-snippet__string">&#34;StaticPlatformPolicy&lt;</span><span class="code-snippet__string"><span class="code-snippet__variable">%d</span></span><span class="code-snippet__string">&gt;: verify_code_directory server is dead\n&#34;</span>);</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">else</span> <span class="code-snippet__keyword">if</span> ( <span class="code-snippet__number">v92</span> )</span></code><br/><code><span leaf=""> {</span></code><br/><code><span leaf="">IOLog(<span class="code-snippet__string">&#34;StaticPlatformPolicy&lt;</span><span class="code-snippet__string"><span class="code-snippet__variable">%d</span></span><span class="code-snippet__string">&gt;: verify_code_directory returned 0x</span><span class="code-snippet__string"><span class="code-snippet__variable">%x</span></span><span class="code-snippet__string">\n&#34;</span>);</span></code><br/><code><span leaf=""> }</span></code><br/></pre></p><p style=""><span lang="EN-US"><span leaf="">    当用户态</span></span><span lang="EN-US"><span leaf="">amfid</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">进程返回出错码，则直接返回。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf="">*(_OWORD *)v125 = *(_OWORD *)v126;</span></code><br/><code><span leaf=""> *(_OWORD *)&amp;v125[<span class="code-snippet__number">16</span>] = *(_OWORD *)v127;</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> ( (<span class="code-snippet__type">unsigned</span> <span class="code-snippet__type">int</span>)<span class="code-snippet__built_in">tokenIsTrusted</span>((<span class="code-snippet__type">audit_token_t</span> *)v125) )</span></code><br/><code><span leaf=""> {</span></code><br/><code><span leaf=""> v62 = v118 != <span class="code-snippet__number">0</span>;</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> ( v120 == <span class="code-snippet__number">1</span> )</span></code><br/><code><span leaf=""> {</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> ( !<span class="code-snippet__built_in">memcmp</span>(v68, &amp;v123[<span class="code-snippet__number">1</span>], <span class="code-snippet__number">20uLL</span>) )</span></code><br/><code><span leaf=""> {</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> ( <span class="code-snippet__built_in">HIDWORD</span>(v121) )</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">panic</span>(<span class="code-snippet__string">&#34;\&#34;amfid is broken. (%s) (%d) (%d) (%d)\&#34;&#34;</span>, (<span class="code-snippet__type">const</span> <span class="code-snippet__type">char</span> *)v61 + <span class="code-snippet__number">8</span>, v88, v120, <span class="code-snippet__built_in">HIDWORD</span>(v121));</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> ( (_DWORD)v121 )</span></code><br/><code><span leaf=""> *a3 |= <span class="code-snippet__number">0x40000000u</span>;             <span class="code-snippet__comment">// CS_DEV_CODE</span></span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> ( v119 )</span></code><br/><code><span leaf=""> *a3 &amp;= ~<span class="code-snippet__number">0x800u</span>;                 <span class="code-snippet__comment">// CS_RESTRICT</span></span></code><br/><code><span leaf=""> v87 = <span class="code-snippet__built_in">BYTE4</span>(v118);</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> ( <span class="code-snippet__built_in">HIDWORD</span>(v118) )</span></code><br/><code><span leaf=""> {</span></code><br/><code><span leaf=""> v87 = <span class="code-snippet__number">0</span>;</span></code><br/><code><span leaf=""> *a3 |= <span class="code-snippet__number">0x4200u</span>;                 <span class="code-snippet__comment">// CS_KILL|CS_ENTITLEMENTS_VALIDATED</span></span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> v86 = <span class="code-snippet__number">1</span>;</span></code><br/><code><span leaf="">LABEL_115:</span></code><br/><code><span leaf=""> v63 = v105;</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> ( (v87 &amp; <span class="code-snippet__number">1</span>) == <span class="code-snippet__number">0</span> )</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">goto</span> LABEL_117;</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">goto</span> LABEL_116;</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">IOLog</span>(<span class="code-snippet__string">&#34;%s: Possible race detected. Rejecting.\n&#34;</span>, (<span class="code-snippet__type">const</span> <span class="code-snippet__type">char</span> *)v61 + <span class="code-snippet__number">8</span>);</span></code><br/><code><span leaf=""><span class="code-snippet__built_in">IOLog</span>(<span class="code-snippet__string">&#34;StaticPlatformPolicy&lt;%d&gt;: Unable to match identity\n&#34;</span>, <span class="code-snippet__number">2LL</span>);</span></code><br/></pre></p><p style=""><span lang="EN-US"><span leaf="">    当用户态</span></span><span lang="EN-US"><span leaf="">afmid</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">返回成功时，会先调用</span></span><span lang="EN-US"><span leaf="">tokenIsTrusted</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">传递当前进程的</span></span><span lang="EN-US"><span leaf="">audit_token</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，它根据</span></span><span lang="EN-US"><span leaf="">audit_token</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">找到当前进程的</span></span><span lang="EN-US"><span leaf="">cd hash</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">是否在</span></span><span lang="EN-US"><span leaf="">static trustcache</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">中，以此证明当前内核确实是与</span></span><span lang="EN-US"><span leaf="">amfid</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">进程通讯，同时</span></span><span lang="EN-US"><span leaf="">amfid</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">会返回给内核一个</span></span><span lang="EN-US"><span leaf="">cd hash</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">值，如果与当前进程的</span></span><span lang="EN-US"><span leaf="">cd hash</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">值相同，则验证通过。根据不同的返回值设置相应的</span></span><span lang="EN-US"><span leaf="">cs_flags</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，然后返回。</span></span></p><h3><span style="mso-bookmark:_Toc19176;"><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf=""><span textstyle="" style="font-size: 18px;font-weight: bold;">3.2.3 额外的几个服务函数</span></span></span></span></h3><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="markdown"><code><span leaf="">AppleMobileFileIntegrityUserClient::externalMethod(unsigned int, IOExternalMethodArguments <span class="code-snippet__emphasis">*, IOExternalMethodDispatch *</span>, OSObject <span class="code-snippet__emphasis">*, void *</span>)::methods</span></code><br/><code><span leaf="">DCQ <span class="code-snippet__strong">__ZN34AppleMobileFileIntegrityUserClient14loadTrustCacheEP8OSObjectPvP25IOExternalMethodArguments</span></span></code><br/><code><span leaf="">DCQ __ZN34AppleMobileFileIntegrityUserClient19flushAllValidationsEP8OSObjectPvP25IOExternalMethodArguments</span></code><br/><code><span leaf="">DCQ <span class="code-snippet__strong">__ZN34AppleMobileFileIntegrityUserClient39loadCompilationServiceCodeDirectoryHashEP8OSObjectPvP25IOExternalMethodArguments</span></span></code><br/><code><span leaf="">DCQ __ZN34AppleMobileFileIntegrityUserClient20isCdhashInTrustCacheEP8OSObjectPvP25IOExternalMethodArguments</span></code><br/><code><span leaf="">DCQ <span class="code-snippet__strong">__ZN34AppleMobileFileIntegrityUserClient14loadTrustCacheEP8OSObjectPvP25IOExternalMethodArguments</span></span></code><br/><code><span leaf="">DCQ __ZN34AppleMobileFileIntegrityUserClient17validateSignatureEP8OSObjectPvP25IOExternalMethodArguments</span></code><br/><code><span leaf="">DCQ <span class="code-snippet__strong">__ZN34AppleMobileFileIntegrityUserClient11setDenylistEP8OSObjectPvP25IOExternalMethodArguments</span></span></code><br/></pre></p><p><span lang="EN-US"><span leaf=""><span textstyle="" style="font-weight: bold;">3.2.3.1 loadTrustCache</span></span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="javascript"><code><span leaf="">_int64 __fastcall <span class="code-snippet__title">AppleMobileFileIntegrityUserClient</span>::<span class="code-snippet__title">loadTrustCache</span>(</span></code><br/><code><span leaf="">AppleMobileFileIntegrityUserClient *<span class="code-snippet__variable">this</span>,</span></code><br/><code><span leaf="">OSObject *a2,</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">void</span> *a3,</span></code><br/><code><span leaf="">IOExternalMethodArguments *a4)</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""> v6 = <span class="code-snippet__title">proc_selfpid</span>();</span></code><br/><code><span leaf=""><span class="code-snippet__title">IOLog</span>(</span></code><br/><code><span leaf=""><span class="code-snippet__string">&#34;%s: PID %d is requesting a trust cache load\n&#34;</span>,</span></code><br/><code><span leaf=""><span class="code-snippet__string">&#34;static IOReturn AppleMobileFileIntegrityUserClient::loadTrustCache(OSObject *, void *, IOExternalMethodArguments *)&#34;</span>,</span></code><br/><code><span leaf="">v6);</span></code><br/></pre></p><p><span leaf="">    每次加载都产生一次日志。</span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="perl"><code><span leaf="">Bool = AppleMobileFileIntegrity::AMFIEntitlementGetBool(</span></code><br/><code><span leaf=""><span class="code-snippet__number">v9</span>,</span></code><br/><code><span leaf="">(proc *)<span class="code-snippet__string">&#34;com.apple.private.amfi.can-load-trust-cache&#34;</span>,</span></code><br/><code><span leaf="">&amp;<span class="code-snippet__number">v30</span>,</span></code><br/><code><span leaf=""><span class="code-snippet__number">v10</span>);</span></code><br/><code><span leaf="">proc_rele(<span class="code-snippet__number">v11</span>);</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> ( Bool )</span></code><br/><code><span leaf=""> {</span></code><br/><code><span leaf="">proc_selfpid();</span></code><br/><code><span leaf="">IOLog(<span class="code-snippet__string">&#34;</span><span class="code-snippet__string"><span class="code-snippet__variable">%s</span></span><span class="code-snippet__string">: failure getting load trust cache entitlement for process </span><span class="code-snippet__string"><span class="code-snippet__variable">%d</span></span><span class="code-snippet__string">\n&#34;</span>);</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">return</span> 3758097089LL;</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> ( !<span class="code-snippet__number">v30</span> )</span></code><br/><code><span leaf=""> {</span></code><br/><code><span leaf="">proc_selfpid();</span></code><br/><code><span leaf="">IOLog(<span class="code-snippet__string">&#34;</span><span class="code-snippet__string"><span class="code-snippet__variable">%s</span></span><span class="code-snippet__string">: process </span><span class="code-snippet__string"><span class="code-snippet__variable">%d</span></span><span class="code-snippet__string"> not allowed to load trust cache\n&#34;</span>);</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">return</span> 3758097089LL;</span></code><br/><code><span leaf=""> }</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    判断当前进程是否由</span></span><span lang="EN-US"><span leaf="">com.apple.private.amfi.can-load-trust-cache</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">这个</span></span><span lang="EN-US"><span leaf="">entitlement</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf="">v17 = *((<span class="code-snippet__type">unsigned</span> <span class="code-snippet__type">int</span> *)a3 + <span class="code-snippet__number">1</span>);</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> ( (_DWORD)v17 == <span class="code-snippet__number">7</span> )</span></code><br/><code><span leaf=""> {</span></code><br/></pre></p><p style=""><span lang="EN-US"><span leaf="">    V17</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">代表</span></span><span lang="EN-US"><span leaf="">trustcache</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">类型，</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">为</span></span><span lang="EN-US"><span leaf="">7</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">表示携带</span></span><span lang="EN-US"><span leaf="">manifest</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">信息。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf="">v19 = AppleMobileFileIntegrityUserClient::<span class="code-snippet__built_in">copyTrustCacheAndManifestFromInputArgument</span>(</span></code><br/><code><span leaf="">(AppleMobileFileIntegrityUserClient *)a3,</span></code><br/><code><span leaf="">(IOExternalMethodArguments *)&amp;v28,</span></code><br/><code><span leaf="">(<span class="code-snippet__type">void</span> **)&amp;v29,</span></code><br/><code><span leaf="">(<span class="code-snippet__type">unsigned</span> __int64 *)&amp;v26,</span></code><br/><code><span leaf="">(<span class="code-snippet__type">void</span> **)&amp;v27,</span></code><br/><code><span leaf="">&amp;v24,</span></code><br/><code><span leaf="">&amp;v25,</span></code><br/><code><span leaf="">v14);</span></code><br/><code><span leaf="">v15 = v19;</span></code><br/><code><span leaf=""> TrustCacheWithExternalManifest = AppleMobileFileIntegrity::<span class="code-snippet__built_in">loadTrustCacheWithExternalManifest</span>(</span></code><br/><code><span leaf=""> v8,</span></code><br/><code><span leaf=""> v26,</span></code><br/><code><span leaf=""> v27,</span></code><br/><code><span leaf=""> (<span class="code-snippet__type">void</span> *)v24,</span></code><br/><code><span leaf="">(<span class="code-snippet__type">unsigned</span> __int64)v25);</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    copyTrustCacheAndManifestFromInputArgument</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">函数做格式检查，最后调用</span></span><span lang="EN-US"><span leaf="">loadTrustCacheWithExternalManifest</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">函数装载</span></span><span lang="EN-US"><span leaf="">trustcache</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">。</span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">    如果</span></span><span lang="EN-US"><span leaf="">v17</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">不为</span></span><span lang="EN-US"><span leaf="">7</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，代表</span></span><span lang="EN-US"><span leaf="">trustcache</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">不携带</span></span><span lang="EN-US"><span leaf="">manifest</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">信息，调用</span></span><span lang="EN-US"><span leaf="">loadTrustCache</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">函数进行装载。</span></span></p><p style=""><span lang="EN-US"><span leaf="">    loadTrustCacheWithExternalManifest</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">和</span></span><span lang="EN-US"><span leaf="">loadTrustCache</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">最终会调用</span></span><span lang="EN-US"><span leaf="">loadTrustCacheWithExternalManifest</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">函数，它又进一步调用</span></span><span lang="EN-US"><span leaf="">pmap_load_image4_trust_cache</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">，这个函数是</span></span><span lang="EN-US"><span leaf="">ppl</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">提供的服务函数。</span></span></p><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">它的功能是将一个</span></span><span lang="EN-US"><span leaf="">imag4</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">类型的</span></span><span lang="EN-US"><span leaf="">trustcache</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">保存到</span></span><span lang="EN-US"><span leaf="">ppl</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">中。</span></span></p><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">第一个参数指向</span></span><span lang="EN-US"><span leaf="">struct image4_trust_cache</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">结构体，</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">第二个参数为它的大小，</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">第三个参数为</span></span><span lang="EN-US"><span leaf="">image4 manifest buffer</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，结构不详，第四个参数为</span></span><span lang="EN-US"><span leaf="">manifest buffer</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">大小。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="makefile"><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE078 BL              _pmap_reserve_ppl_page</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE07C CMP             W0, #6</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE080 B.NE            loc_FFFFFFF0097FE08C</span></span></code><br/><code><span leaf="">首先调用_pmap_reserve_ppl_page从ppl中获取一个page，然后挂接到_pmap_reserved_page_list中。</span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE08C loc_FFFFFFF0097FE08C ; CODE XREF: _pmap_load_image4_trust_cache_internal+48↑j</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE08C MOV             W8, #0x10000000</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE090 CMP             X21, X8</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE094 B.LS            loc_FFFFFFF0097FE0A0 ; x1 &lt; 0x10000000</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE098 MOV             W25, #0xFFFFFFFA</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE09C B               loc_FFFFFFF0097FE30C</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE0A0 ; ---------------------------------------------------------------------------</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE0A0</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE0A0 loc_FFFFFFF0097FE0A0 ; CODE XREF: _pmap_load_image4_trust_cache_internal+5C↑j</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE0A0 MOV             W8, #0x10000000</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE0A4 CMP             X19, X8</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE0A8 B.LS            loc_FFFFFFF0097FE0B4 ; x3 &lt; 0x10000000</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE0AC MOV             W25, #0xFFFFFFF8</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE0B0 B               loc_FFFFFFF0097FE30C</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE0B4 ; -----------------------------------------------------</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE0B4 loc_FFFFFFF0097FE0B4 ; CODE XREF: _pmap_load_image4_trust_cache_internal+70↑j</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE0B4 CMN             X22, X21</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE0B8 B.CS            loc_FFFFFFF0097FE514 ; x0 + x1 &lt; x0</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE0BC CMN             X20, X19</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE0C0 B.CS            loc_FFFFFFF0097FE524 ; x3 + x4 &lt; x3</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE0C4 TST             X22, #0x3FFF</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE0C8 B.NE            loc_FFFFFFF0097FE534 ; x0 &amp; 0x3fff</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE0CC TST             X21, #0x3FFF ; x1 &amp; 0x3fff</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE0D0 B.NE            loc_FFFFFFF0097FE544</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE0D4 TST             X20, #0x3FFF</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE0D8 B.NE            loc_FFFFFFF0097FE554 ; x2 &amp; 0x3fff</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE0DC TST             X19, #0x3FFF</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE0E0 B.NE            loc_FFFFFFF0097FE564 ; x3 &amp; 0x3fff</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE0E4 CMP             X21, #0x57 ; &#39;W&#39;</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE0E8 B.LS            loc_FFFFFFF0097FE574 ; x1 &lt; 0x57</span></span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    一个</span></span><span lang="EN-US"><span leaf="">image4_trust_cache</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">和其</span></span><span lang="EN-US"><span leaf="">manifest buffer</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">地址必须以</span></span><span lang="EN-US"><span leaf="">0x4000</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">对齐，并且大小不能超过</span></span><span lang="EN-US"><span leaf="">0x10000000</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，</span></span><span lang="EN-US"><span leaf=""> image4_trust_cache</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">不能小于</span></span><span lang="EN-US"><span leaf="">0x57</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="makefile"><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE0EC MOV             X0, X22</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE0F0 MOV             X1, X21</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE0F4 BL              _pmap_ppl_lockdown_pages</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE0F8 CBZ             X19, loc_FFFFFFF0097FE108</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE0FC MOV             X0, X20</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE100 MOV             X1, X19</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE104 BL              _pmap_ppl_lockdown_pages</span></span></code><br/></pre></p><p><span lang="EN-US"><span leaf=""> 调用</span></span><span lang="EN-US"><span leaf="">_pmap_ppl_lockdown_pages</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">在</span></span><span lang="EN-US"><span leaf="">ppl</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">中分别锁定</span></span><span lang="EN-US"><span leaf="">image4_trust_cache</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">和</span></span><span lang="EN-US"><span leaf="">manifest buffer</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">物理页。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="makefile"><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE128 BL              _pmap_get_current_csidentity</span></span></code></pre></p><p><span lang="EN-US"><span leaf="">    获取调用进程的</span></span><span lang="EN-US"><span leaf="">csidentity</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="makefile"><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE130 ADRL            X8, aComAppleMobile ; &#34;com.apple.mobile.softwareupdated&#34;</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE138 MOV             X9, X0</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE13C</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE13C loc_FFFFFFF0097FE13C ; CODE XREF: _pmap_load_image4_trust_cache_internal+11C↓j</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE13C LDRB            W10, [X9]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE140 LDRB            W11, [X8] ; &#34;com.apple.mobile.softwareupdated&#34;</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE144 CMP             W10, W11</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE148 B.NE            loc_FFFFFFF0097FE16C</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE14C ADD             X8, X8, #1</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE150 ADD             X9, X9, #1</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE154 CBNZ            W10, loc_FFFFFFF0097FE13C</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE158</span></span></code><br/></pre></p><p><span lang="EN-US"><span leaf=""> 通过上述代码判断进程的</span></span><span lang="EN-US"><span leaf="">csidentity</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">是否为</span></span><span lang="EN-US"><span leaf="">com.apple.mobile.softwareupdated</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">com.apple.load_trust_cache</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">com.apple.security.cryptexd</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">com.apple.MobileStorageMounter</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">、</span></span></p><p><span lang="EN-US"><span leaf="">com.apple.security.cryptexctl</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">。如果进程</span></span><span lang="EN-US"><span leaf="">csidentity</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">不是这些中的一个，</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">则直接返回。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="makefile"><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE22C loc_FFFFFFF0097FE22C ; CODE XREF: _pmap_load_image4_trust_cache_internal+128↑j</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE22C ; _pmap_load_image4_trust_cache_internal+164↑j ...</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE22C ADD             X27, X22, #0x58 ; &#39;X&#39;</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE230 LDR             X1, [X22,#0x50]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE234 ADD             X6, SP, #0x70+var_58 ; uuid</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE238 ADD             X7, SP, #0x70+var_60</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE23C MOV             X0, X27</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE240 MOV             X2, X20</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE244 MOV             X3, X24</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE248 MOV             W4, #0x6C747273</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE250 MOV             X5, X26</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE254 BL              _pmap_validate_image4</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE258 CBZ             W0, loc_FFFFFFF0097FE2A4</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE25C MOV             X25, X0</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE260 CBZ             W28, loc_FFFFFFF0097FE2EC</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE264 CMP             W26, #1</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE268 B.NE            loc_FFFFFFF0097FE2EC</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE26C CMP             W25, W28</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE270 B.NE            loc_FFFFFFF0097FE2EC</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE274 LDR             X1, [X22,#0x50]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE278 ADD             X6, SP, #0x70+var_58</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE27C ADD             X7, SP, #0x70+var_60</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE280 MOV             X0, X27</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE284 MOV             X2, X20</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE288 MOV             X3, X24</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE28C MOV             W4, #0x6C747273</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE294 MOV             W5, #4</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE298 BL              _pmap_validate_image4</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE29C MOV             X25, X0</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE2A0 CBNZ            W0, loc_FFFFFFF0097FE2EC</span></span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    调用</span></span><span lang="EN-US"><span leaf="">_pmap_validate_image4</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">验证</span></span><span lang="EN-US"><span leaf="">image4_trust_cache</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">和其</span></span><span lang="EN-US"><span leaf="">manifest buffer</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">结构合法性，</span></span><span lang="EN-US"><span leaf="">var_58</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">保存的是</span></span><span lang="EN-US"><span leaf="">image4</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">的</span></span><span lang="EN-US"><span leaf="">uuid</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="makefile"><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE330 loc_FFFFFFF0097FE330 ; CODE XREF: _pmap_load_image4_trust_cache_internal+2A4↑j</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE330 ADR             X24, _pmap_loaded_trust_caches_lock</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE334 NOP</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE338 MOV             X0, X24</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE33C BL              _hw_lock_lock_nopreempt</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE340 ADRP            X27, #_pmap_image4_trust_caches@PAGE</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE344 LDR             X8, [X27,#_pmap_image4_trust_caches@PAGEOFF]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE348 CBZ             X8, loc_FFFFFFF0097FE478</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE34C LDR             X9, [SP,#0x70+var_58]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE350 B               loc_FFFFFFF0097FE35C ; struct trust_cache_entry1 {</span></span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    pmap_image4_trust_caches</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">数组保存的是</span></span><span lang="EN-US"><span leaf="">ppl</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">中所有的</span></span><span lang="EN-US"><span leaf="">image4</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">结构体内容，</span></span><span lang="EN-US"><span leaf="">xnu</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">源码在某个版本中泄露过</span></span><span lang="EN-US"><span leaf="">struct image4_trust_cache</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">的结构体。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf="">osfmk/kern/trustcache.h</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">trust_cache_entry1</span> {</span></code><br/><code><span leaf=""><span class="code-snippet__type">uint8_t</span> cdhash[CS_CDHASH_LEN];</span></code><br/><code><span leaf=""><span class="code-snippet__type">uint8_t</span> hash_type;</span></code><br/><code><span leaf=""><span class="code-snippet__type">uint8_t</span> flags;</span></code><br/><code><span leaf="">} __attribute__((__packed__));</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">trust_cache_module1</span> {</span></code><br/><code><span leaf=""><span class="code-snippet__type">uint32_t</span> version;</span></code><br/><code><span leaf=""><span class="code-snippet__type">uuid_t</span> uuid;</span></code><br/><code><span leaf=""><span class="code-snippet__type">uint32_t</span> num_entries;</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">trust_cache_entry1</span> entries[];</span></code><br/><code><span leaf="">} __attribute__((__packed__));</span></code><br/><code><span leaf="">osfmk/vm/pmap.h</span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">define</span></span><span class="code-snippet__meta"> PMAP_IMAGE4_TRUST_CACHE_HAS_TYPE 1</span></span></code><br/><code><span leaf=""><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">pmap_image4_trust_cache</span> {</span></code><br/><code><span leaf=""> <span class="code-snippet__comment">// Filled by pmap layer.</span></span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">pmap_image4_trust_cache</span> <span class="code-snippet__type">const</span> *next;            <span class="code-snippet__comment">// linked list linkage</span></span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">trust_cache_module1</span> <span class="code-snippet__type">const</span> *<span class="code-snippet__keyword">module</span>;                       <span class="code-snippet__comment">// pointer into module (within data below)</span></span></code><br/><code><span leaf=""> <span class="code-snippet__comment">// Filled by caller.</span></span></code><br/><code><span leaf=""> <span class="code-snippet__comment">// data is either an image4,</span></span></code><br/><code><span leaf=""> <span class="code-snippet__comment">// or just the trust cache payload itself if the image4 manifest is external.</span></span></code><br/><code><span leaf=""> <span class="code-snippet__type">pmap_tc_type_t</span> type;</span></code><br/><code><span leaf=""> <span class="code-snippet__type">size_t</span> bnch_len;</span></code><br/><code><span leaf=""> <span class="code-snippet__type">uint8_t</span> <span class="code-snippet__type">const</span> bnch[<span class="code-snippet__number">48</span>];</span></code><br/><code><span leaf=""> <span class="code-snippet__type">size_t</span> data_len;</span></code><br/><code><span leaf=""> <span class="code-snippet__type">uint8_t</span> <span class="code-snippet__type">const</span> data[];</span></code><br/><code><span leaf="">};</span></code><br/></pre></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="makefile"><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE354 loc_FFFFFFF0097FE354 ; CODE XREF: _pmap_load_image4_trust_cache_internal+334↓j</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE354 ; _pmap_load_image4_trust_cache_internal+344↓j ...</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE354 LDR             X8, [X8] ; cache_entry = cache_entry-&gt;next</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE358 CBZ             X8, loc_FFFFFFF0097FE478</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE35C</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE35C loc_FFFFFFF0097FE35C ; CODE XREF: _pmap_load_image4_trust_cache_internal+318↑j</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE35C LDR             X10, [X8,#8] ; module = cache_entry-&gt;module</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE360 LDRB            W11, [X9,#4]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE364 LDRB            W12, [X10,#4] ; module-&gt;uuid[0]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE368 CMP             W11, W12</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE36C B.NE            loc_FFFFFFF0097FE354 ; cache_entry = cache_entry-&gt;next</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE370 LDRB            W11, [X9,#5]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE374 LDRB            W12, [X10,#5] ; module-&gt;uuid[1]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE378 CMP             W11, W12</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE37C B.NE            loc_FFFFFFF0097FE354 ; cache_entry = cache_entry-&gt;next</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE380 LDRB            W11, [X9,#6]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE384 LDRB            W12, [X10,#6] ; module-&gt;uuid[2]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE388 CMP             W11, W12</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE38C B.NE            loc_FFFFFFF0097FE354 ; cache_entry = cache_entry-&gt;next</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE390 LDRB            W11, [X9,#7]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE394 LDRB            W12, [X10,#7] ; module-&gt;uuid[3]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE398 CMP             W11, W12</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE39C B.NE            loc_FFFFFFF0097FE354 ; cache_entry = cache_entry-&gt;next</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE3A0 LDRB            W11, [X9,#8]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE3A4 LDRB            W12, [X10,#8] ; module-&gt;uuid[4]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE3A8 CMP             W11, W12</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE3AC B.NE            loc_FFFFFFF0097FE354 ; cache_entry = cache_entry-&gt;next</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE3B0 LDRB            W11, [X9,#9]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE3B4 LDRB            W12, [X10,#9] ; module-&gt;uuid[5]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE3B8 CMP             W11, W12</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE3BC B.NE            loc_FFFFFFF0097FE354 ; cache_entry = cache_entry-&gt;next</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE3C0 LDRB            W11, [X9,#0xA]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE3C4 LDRB            W12, [X10,#0xA] ; module-&gt;uuid[6]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE3C8 CMP             W11, W12</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE3CC B.NE            loc_FFFFFFF0097FE354 ; cache_entry = cache_entry-&gt;next</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE3D0 LDRB            W11, [X9,#0xB]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE3D4 LDRB            W12, [X10,#0xB] ; module-&gt;uuid[7]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE3D8 CMP             W11, W12</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE3DC B.NE            loc_FFFFFFF0097FE354 ; cache_entry = cache_entry-&gt;next</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE3E0 LDRB            W11, [X9,#0xC]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE3E4 LDRB            W12, [X10,#0xC] ; module-&gt;uuid[8]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE3E8 CMP             W11, W12</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE3EC B.NE            loc_FFFFFFF0097FE354 ; cache_entry = cache_entry-&gt;next</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE3F0 LDRB            W11, [X9,#0xD]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE3F4 LDRB            W12, [X10,#0xD] ; module-&gt;uuid[9]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE3F8 CMP             W11, W12</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE3FC B.NE            loc_FFFFFFF0097FE354 ; cache_entry = cache_entry-&gt;next</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE400 LDRB            W11, [X9,#0xE]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE404 LDRB            W12, [X10,#0xE] ; module-&gt;uuid[10]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE408 CMP             W11, W12</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE40C B.NE            loc_FFFFFFF0097FE354 ; cache_entry = cache_entry-&gt;next</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE410 LDRB            W11, [X9,#0xF]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE414 LDRB            W12, [X10,#0xF] ; module-&gt;uuid[11]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE418 CMP             W11, W12</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE41C B.NE            loc_FFFFFFF0097FE354 ; cache_entry = cache_entry-&gt;next</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE420 LDRB            W11, [X9,#0x10]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE424 LDRB            W12, [X10,#0x10] ; module-&gt;uuid[12]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE428 CMP             W11, W12</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE42C B.NE            loc_FFFFFFF0097FE354 ; cache_entry = cache_entry-&gt;next</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE430 LDRB            W11, [X9,#0x11]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE434 LDRB            W12, [X10,#0x11] ; module-&gt;uuid[13]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE438 CMP             W11, W12</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE43C B.NE            loc_FFFFFFF0097FE354 ; cache_entry = cache_entry-&gt;next</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE440 LDRB            W11, [X9,#0x12]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE444 LDRB            W12, [X10,#0x12] ; module-&gt;uuid[14]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE448 CMP             W11, W12</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE44C B.NE            loc_FFFFFFF0097FE354 ; cache_entry = cache_entry-&gt;next</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE450 LDRB            W11, [X9,#0x13]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE454 LDRB            W10, [X10,#0x13] ; module-&gt;uuid[15]</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE458 CMP             W11, W10</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__PPLTEXT:__text:FFFFFFF0097FE45C B.NE            loc_FFFFFFF0097FE354 ; cache_entry = cache_entry-&gt;next</span></span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    通过一个循环判断要保存的</span></span><span lang="EN-US"><span leaf="">image4 cache</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">对应的</span></span><span lang="EN-US"><span leaf="">uuid</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">是否已经在</span></span><span lang="EN-US"><span leaf="">pmap_image4_trust_caches</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">数组中。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="markdown"><code><span leaf=""><span class="code-snippet__strong">__PPLTEXT:__</span>text:FFFFFFF0097FE478 loc<span class="code-snippet__emphasis">_FFFFFFF0097FE478 ; CODE XREF: _</span>pmap<span class="code-snippet__emphasis">_load_</span>image4<span class="code-snippet__emphasis">_trust_</span>cache<span class="code-snippet__emphasis">_internal+310↑j</span></span></code><br/><code><span leaf=""><span class="code-snippet__strong">__PPLTEXT:__</span>text:FFFFFFF0097FE478 ; _pmap<span class="code-snippet__emphasis">_load_</span>image4<span class="code-snippet__emphasis">_trust_</span>cache<span class="code-snippet__emphasis">_internal+320↑j</span></span></code><br/><code><span leaf=""><span class="code-snippet__strong">__PPLTEXT:__</span>text:FFFFFFF0097FE478 MOV             X0, X22</span></code><br/><code><span leaf=""><span class="code-snippet__strong">__PPLTEXT:__</span>text:FFFFFFF0097FE47C BL              _mmu<span class="code-snippet__emphasis">_kvtop</span></span></code><br/><code><span leaf=""><span class="code-snippet__strong">__PPLTEXT:__</span>text:FFFFFFF0097FE480 CBNZ            X0, loc_FFFFFFF0097FE498</span></code><br/><code><span leaf=""><span class="code-snippet__strong">__PPLTEXT:__</span>text:FFFFFFF0097FE484 ADRP            X8, #<span class="code-snippet__emphasis">_kernel_</span>pmap@PAGE</span></code><br/><code><span leaf=""><span class="code-snippet__strong">__PPLTEXT:__</span>text:FFFFFFF0097FE488 LDR             X0, [X8,#<span class="code-snippet__emphasis">_kernel_</span>pmap@PAGEOFF]</span></code><br/><code><span leaf=""><span class="code-snippet__strong">__PPLTEXT:__</span>text:FFFFFFF0097FE48C MOV             X1, X22</span></code><br/><code><span leaf=""><span class="code-snippet__strong">__PPLTEXT:__</span>text:FFFFFFF0097FE490 BL              <span class="code-snippet__emphasis">_pmap_</span>vtophys</span></code><br/><code><span leaf=""><span class="code-snippet__strong">__PPLTEXT:__</span>text:FFFFFFF0097FE494 LSL             X0, X0, <a class="wx_topic_link" topic-id="mjxki4n3-sxinoc" style="color: #576B95 !important;" data-topic="1">#0xE</a></span></code><br/><code><span leaf=""><span class="code-snippet__strong">__PPLTEXT:__</span>text:FFFFFFF0097FE498</span></code><br/><code><span leaf=""><span class="code-snippet__strong">__PPLTEXT:__</span>text:FFFFFFF0097FE498 loc<span class="code-snippet__emphasis">_FFFFFFF0097FE498 ; CODE XREF: _</span>pmap<span class="code-snippet__emphasis">_load_</span>image4<span class="code-snippet__emphasis">_trust_</span>cache<span class="code-snippet__emphasis">_internal+448↑j</span></span></code><br/><code><span leaf=""><span class="code-snippet__strong">__PPLTEXT:__</span>text:FFFFFFF0097FE498 BL              _phystokv</span></code><br/><code><span leaf=""><span class="code-snippet__strong">__PPLTEXT:__</span>text:FFFFFFF0097FE49C MOV             X25, X0 ; start</span></code><br/><code><span leaf=""><span class="code-snippet__strong">__PPLTEXT:__</span>text:FFFFFFF0097FE4A0 ADD             X26, X0, <a class="wx_topic_link" topic-id="mjxki4n3-52ugzl" style="color: #576B95 !important;" data-topic="1">#4</a>,LSL<a class="wx_topic_link" topic-id="mjxki4n3-jsnarx" style="color: #576B95 !important;" data-topic="1">#12</a> ; end = x0 + 4 &lt;&lt; 12</span></code><br/><code><span leaf=""><span class="code-snippet__strong">__PPLTEXT:__</span>text:FFFFFFF0097FE4A4 MOV             X1, X26</span></code><br/><code><span leaf=""><span class="code-snippet__strong">__PPLTEXT:__</span>text:FFFFFFF0097FE4A8 MOV             W2, <a class="wx_topic_link" topic-id="mjxki4n3-yomf7y" style="color: #576B95 !important;" data-topic="1">#0xB</a></span></code><br/><code><span leaf=""><span class="code-snippet__strong">__PPLTEXT:__</span>text:FFFFFFF0097FE4AC MOV             W3, <a class="wx_topic_link" topic-id="mjxki4n3-7rjegx" style="color: #576B95 !important;" data-topic="1">#1</a></span></code><br/><code><span leaf=""><span class="code-snippet__strong">__PPLTEXT:__</span>text:FFFFFFF0097FE4B0 BL              <span class="code-snippet__emphasis">_pmap_</span>set<span class="code-snippet__emphasis">_range_</span>xprr<span class="code-snippet__emphasis">_perm ; (start, end, 0xb, 1)</span></span></code><br/><code><span leaf=""><span class="code-snippet__strong">__PPLTEXT:__</span>text:FFFFFFF0097FE4B4 LDR             X8, [SP,<a class="wx_topic_link" topic-id="mjxki4n3-okdx0p" style="color: #576B95 !important;" data-topic="1">#0x70</a>+var_58]</span></code><br/><code><span leaf=""><span class="code-snippet__strong">__PPLTEXT:__</span>text:FFFFFFF0097FE4B8 STR             X8, [X25,<a class="wx_topic_link" topic-id="mjxki4n3-ienzuy" style="color: #576B95 !important;" data-topic="1">#8</a>] ; <span class="code-snippet__emphasis">*(start + 8) = var_58</span></span></code><br/><code><span leaf=""><span class="code-snippet__strong">__PPLTEXT:__</span>text:FFFFFFF0097FE4BC LDR             X8, [X27,#_pmap_image4_trust_caches@PAGEOFF]</span></code><br/><code><span leaf=""><span class="code-snippet__strong">__PPLTEXT:__</span>text:FFFFFFF0097FE4C0 STR             X8, [X25] ; *(start + 0) = <span class="code-snippet__emphasis">_pmap_</span>image4<span class="code-snippet__emphasis">_trust_</span>caches</span></code><br/><code><span leaf=""><span class="code-snippet__strong">__PPLTEXT:__</span>text:FFFFFFF0097FE4C4 MOV             X0, X25</span></code><br/><code><span leaf=""><span class="code-snippet__strong">__PPLTEXT:__</span>text:FFFFFFF0097FE4C8 MOV             X1, X26</span></code><br/><code><span leaf=""><span class="code-snippet__strong">__PPLTEXT:__</span>text:FFFFFFF0097FE4CC MOV             W2, <a class="wx_topic_link" topic-id="mjxki4n3-s98r41" style="color: #576B95 !important;" data-topic="1">#1</a></span></code><br/><code><span leaf=""><span class="code-snippet__strong">__PPLTEXT:__</span>text:FFFFFFF0097FE4D0 MOV             W3, <a class="wx_topic_link" topic-id="mjxki4n3-hpygyl" style="color: #576B95 !important;" data-topic="1">#0xB</a></span></code><br/><code><span leaf=""><span class="code-snippet__strong">__PPLTEXT:__</span>text:FFFFFFF0097FE4D4 BL              <span class="code-snippet__emphasis">_pmap_</span>set<span class="code-snippet__emphasis">_range_</span>xprr<span class="code-snippet__emphasis">_perm ; (start, end, 1, 0xb)</span></span></code><br/><code><span leaf=""><span class="code-snippet__strong">__PPLTEXT:__</span>text:FFFFFFF0097FE4F4 loc_FFFFFFF0097FE4F4 ; CODE XREF: <span class="code-snippet__emphasis">_pmap_</span>load<span class="code-snippet__emphasis">_image4_</span>trust<span class="code-snippet__emphasis">_cache_</span>internal+4A0↑j</span></code><br/><code><span leaf=""><span class="code-snippet__strong">__PPLTEXT:__</span>text:FFFFFFF0097FE4F4 STR             X22, [X27,#<span class="code-snippet__emphasis">_pmap_</span>image4<span class="code-snippet__emphasis">_trust_</span>caches@PAGEOFF] ; <span class="code-snippet__emphasis">_pmap_</span>image4<span class="code-snippet__emphasis">_trust_</span>caches = x0</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">  调用</span></span><span lang="EN-US"><span leaf="">pmap_set_range_xprr_perm</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">设置</span></span><span lang="EN-US"><span leaf="">image4 cache</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">的权限，</span></span><span lang="EN-US"><span leaf=""> Image4 cache</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">的</span></span><span lang="EN-US"><span leaf="">next</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">字段设置为</span></span><span lang="EN-US"><span leaf="">pmap_image4_trust_caches</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，</span></span></p><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">然后将</span></span><span lang="EN-US"><span leaf="">image4 cache</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">挂接为</span></span><span lang="EN-US"><span leaf="">pmap_image4_trust_caches</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">数组的第一个元素。</span></span></p><h4><span lang="EN-US"><span leaf=""><span textstyle="" style="font-weight: bold;">3.2.3.2 flushAllValidations</span></span></span></h4><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="javascript"><code><span leaf="">__int64 __fastcall <span class="code-snippet__title">AppleMobileFileIntegrityUserClient</span>::<span class="code-snippet__title">flushAllValidations</span>(</span></code><br/><code><span leaf="">AppleMobileFileIntegrityUserClient *<span class="code-snippet__variable">this</span>,</span></code><br/><code><span leaf="">OSObject *a2,</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">void</span> *a3,</span></code><br/><code><span leaf="">IOExternalMethodArguments *a4)</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> ( v4 &amp;&amp; (v5 = (<span class="code-snippet__title">AppleMobileFileIntegrity</span> *)v4[<span class="code-snippet__number">27</span>].<span class="code-snippet__property">__vftable</span>) != 0LL )</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">return</span> <span class="code-snippet__title">AppleMobileFileIntegrity</span>::<span class="code-snippet__title">purgeCachedValidationResults</span>(v5);</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">else</span></span></code><br/><code><span leaf=""><span class="code-snippet__keyword">return</span> 3758097097LL;</span></code><br/><code><span leaf="">}</span></code><br/><code><span leaf="">__int64 __fastcall <span class="code-snippet__title">AppleMobileFileIntegrity</span>::<span class="code-snippet__title">purgeCachedValidationResults</span>(<span class="code-snippet__params">AppleMobileFileIntegrity *</span><span class="code-snippet__params"><span class="code-snippet__variable">this</span></span>)</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""><span class="code-snippet__title">cs_blob_reset_cache</span>(<span class="code-snippet__variable">this</span>);</span></code><br/><code><span leaf=""> denyUnrestrictedDebuggingCache = <span class="code-snippet__number">0</span>;</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">return</span> 0LL;</span></code><br/><code><span leaf="">}</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">void</span> <span class="code-snippet__title">cs_blob_reset_cache</span>()</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""><span class="code-snippet__title">atomic_fetch_add_explicit</span>(&amp;cs_blob_generation_count, 2u, memory_order_relaxed);</span></code><br/><code><span leaf="">}</span></code><br/></pre></p><p><span lang="EN-US"><span leaf=""><span textstyle="" style="font-weight: bold;">3.2.3.3 loadCompilationServiceCodeDirectoryHash</span></span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="javascript"><code><span leaf="">__int64 __fastcall <span class="code-snippet__title">AppleMobileFileIntegrityUserClient</span>::<span class="code-snippet__title">loadCompilationServiceCodeDirectoryHash</span>(</span></code><br/><code><span leaf="">AppleMobileFileIntegrityUserClient *<span class="code-snippet__variable">this</span>,</span></code><br/><code><span leaf="">OSObject *a2,</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">void</span> *a3,</span></code><br/><code><span leaf="">IOExternalMethodArguments *a4)</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""><span class="code-snippet__title">Bool</span> = <span class="code-snippet__title">AppleMobileFileIntegrity</span>::<span class="code-snippet__title">AMFIEntitlementGetBool</span>(</span></code><br/><code><span leaf=""> v10,</span></code><br/><code><span leaf=""> (proc *)<span class="code-snippet__string">&#34;com.apple.private.amfi.can-load-cdhash&#34;</span>,</span></code><br/><code><span leaf=""> &amp;v15,</span></code><br/><code><span leaf=""> v11);</span></code><br/><code><span leaf=""><span class="code-snippet__title">proc_rele</span>(v12);</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    判断当前进程是否有</span></span><span lang="EN-US"><span leaf="">com.apple.private.amfi.can-load-cdhash</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">这个</span></span><span lang="EN-US"><span leaf="">entitlement</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="css"><code><span leaf="">return AppleMobileFileIntegrity::<span class="code-snippet__built_in">loadCompilationServiceCodeDirectoryHash</span>(v6, v16);</span></code></pre></p><p style=""><span lang="EN-US"><span leaf="">    调用</span></span><span lang="EN-US"><span leaf="">loadCompilationServiceCodeDirectoryHash</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">装载</span></span><span lang="EN-US"><span leaf="">compilationServiceHash</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="javascript"><code><span leaf="">__int64 __fastcall <span class="code-snippet__title">AppleMobileFileIntegrity</span>::<span class="code-snippet__title">loadCompilationServiceCodeDirectoryHash</span>(</span></code><br/><code><span leaf=""> AppleMobileFileIntegrity *<span class="code-snippet__variable">this</span>,</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">const</span> unsigned __int8 *a2)</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""> __int128 v3; <span class="code-snippet__comment">// q0</span></span></code><br/><code><span leaf=""> <span class="code-snippet__title">lck_mtx_lock</span>((<span class="code-snippet__title">IOLock</span> *)compServiceHashLock);</span></code><br/><code><span leaf=""> v3 = *(_OWORD *)a2;</span></code><br/><code><span leaf=""> dword_FFFFFFF009A584B0 = *((_DWORD *)a2 + <span class="code-snippet__number">4</span>);</span></code><br/><code><span leaf=""> compilationServiceHash = v3;</span></code><br/><code><span leaf=""> <span class="code-snippet__title">lck_mtx_unlock</span>((<span class="code-snippet__title">IOLock</span> *)compServiceHashLock);</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">return</span> 0LL;</span></code><br/><code><span leaf="">}</span></code><br/></pre></p><p style=""><span lang="EN-US"><span leaf=""><span textstyle="" style="font-weight: bold;">3.2.3.4 isCdhashInTrustCache</span></span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="javascript"><code><span leaf="">__int64 __fastcall <span class="code-snippet__title">AppleMobileFileIntegrityUserClient</span>::<span class="code-snippet__title">isCdhashInTrustCache</span>(</span></code><br/><code><span leaf="">AppleMobileFileIntegrityUserClient *<span class="code-snippet__variable">this</span>,</span></code><br/><code><span leaf="">OSObject *a2,</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">void</span> *a3,</span></code><br/><code><span leaf="">IOExternalMethodArguments *a4)</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""><span class="code-snippet__title">Bool</span> = <span class="code-snippet__title">AppleMobileFileIntegrity</span>::<span class="code-snippet__title">isCdhashInTrustCache</span>(</span></code><br/><code><span leaf=""> v6,</span></code><br/><code><span leaf=""> *((unsigned __int8 **)a3 + <span class="code-snippet__number">6</span>),</span></code><br/><code><span leaf=""> *((_QWORD *)a3 + <span class="code-snippet__number">4</span>) != 0LL);</span></code><br/><code><span leaf=""><span class="code-snippet__title">proc_selfpid</span>();</span></code><br/><code><span leaf=""><span class="code-snippet__title">IOLog</span>(<span class="code-snippet__string">&#34;%s: Returning IOReturn 0x%x to process %d\n&#34;</span>);</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    调用</span></span><span lang="EN-US"><span leaf="">isCdhashInTrustCache</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">检查用户态进程传递进来的</span></span><span lang="EN-US"><span leaf="">cd hash</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">是否在</span></span><span lang="EN-US"><span leaf="">trustcache</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">中。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf=""><span class="code-snippet__function">__int64 __fastcall </span><span class="code-snippet__function"><span class="code-snippet__title">amfi_is_cdhash_in_trust_cache</span></span><span class="code-snippet__function"><span class="code-snippet__params">(</span></span><span class="code-snippet__function"><span class="code-snippet__params"><span class="code-snippet__type">const</span></span></span><span class="code-snippet__function"><span class="code-snippet__params"><span class="code-snippet__type">unsigned</span></span></span><span class="code-snippet__function"><span class="code-snippet__params"> __int8 *a1, </span></span><span class="code-snippet__function"><span class="code-snippet__params"><span class="code-snippet__type">int</span></span></span><span class="code-snippet__function"><span class="code-snippet__params"> a2)</span></span></span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf="">__int64 result; <span class="code-snippet__comment">// x0</span></span></code><br/><code><span leaf="">result = <span class="code-snippet__built_in">AMFIIsCodeDirectoryInTrustCache</span>(a1);</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> ( (result &amp; <span class="code-snippet__number">1</span>) == <span class="code-snippet__number">0</span> )</span></code><br/><code><span leaf=""> {</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">if</span> ( a2 )</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">return</span> (<span class="code-snippet__type">unsigned</span> <span class="code-snippet__type">int</span>)<span class="code-snippet__built_in">codeDirectoryHashIsInLoadedTrustCache</span>(a1) != <span class="code-snippet__number">0</span>;</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">return</span> result;</span></code><br/><code><span leaf="">}</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">   AMFIIsCodeDirectoryInTrustCache</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">和</span></span><span lang="EN-US"><span leaf="">codeDirectoryHashIsInLoadedTrustCache</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">调用</span></span><span lang="EN-US"><span leaf="">ppl</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">服务函数，</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">检查</span></span><span lang="EN-US"><span leaf="">cd hash</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">是否在</span></span><span lang="EN-US"><span leaf="">static trustcache</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">和</span></span><span lang="EN-US"><span leaf="">loaded trustcache</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">中。</span></span></p><h4><span lang="EN-US"><span leaf=""><span textstyle="" style="font-weight: bold;">3.2.3.5 validateSignature</span></span></span></h4><p style=""><span lang="EN-US"><span leaf="">    AMFI</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">允许用户进程主动传递一个</span></span><span lang="EN-US"><span leaf="">cs_blob</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">来做验签，最终都会调用</span></span><span lang="EN-US"><span leaf="">check_signature</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">函数，</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">参见第</span></span><span lang="EN-US"><span leaf="">2</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">节。</span></span></p><h4><span lang="EN-US"><span leaf=""><span textstyle="" style="font-weight: bold;">3.2.3.6 setDenylist</span></span></span></h4><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="javascript"><code><span leaf="">__int64 __fastcall <span class="code-snippet__title">AppleMobileFileIntegrityUserClient</span>::<span class="code-snippet__title">setDenylist</span>(</span></code><br/><code><span leaf="">AppleMobileFileIntegrityUserClient *<span class="code-snippet__variable">this</span>,</span></code><br/><code><span leaf="">OSObject *a2,</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">void</span> *a3,</span></code><br/><code><span leaf="">IOExternalMethodArguments *a4)</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""><span class="code-snippet__title">Bool</span> = <span class="code-snippet__title">AppleMobileFileIntegrity</span>::<span class="code-snippet__title">AMFIEntitlementGetBool</span>(</span></code><br/><code><span leaf="">v6,</span></code><br/><code><span leaf="">(proc *)<span class="code-snippet__string">&#34;com.apple.private.amfi.can-set-denylist&#34;</span>,</span></code><br/><code><span leaf="">&amp;v18,</span></code><br/><code><span leaf="">v7);</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    判断当前进程是否有</span></span><span lang="EN-US"><span leaf="">com.apple.private.amfi.can-set-denylist</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">这个</span></span><span lang="EN-US"><span leaf="">entitlement</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="kotlin"><code><span leaf=""> <span class="code-snippet__keyword">if</span> ( (ValidateBlacklist(v15, v11) &amp; <span class="code-snippet__number">1</span>) != <span class="code-snippet__number">0</span> )</span></code><br/><code><span leaf=""> {</span></code><br/><code><span leaf=""> UpdateBlacklist(v15, v11);</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">return</span> 0LL;</span></code><br/><code><span leaf=""> }</span></code><br/></pre></p><p style=""><span lang="EN-US"><span leaf="">    ValidateBlacklist</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">函数判断要检查的</span></span><span lang="EN-US"><span leaf="">cd hash</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">是否已在</span></span><span lang="EN-US"><span leaf="">blacklist</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">中。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cs"><code><span leaf=""><span class="code-snippet__keyword">void</span> __<span class="code-snippet__function">fastcall </span><span class="code-snippet__function"><span class="code-snippet__title">UpdateBlacklist</span></span><span class="code-snippet__function">(</span><span class="code-snippet__function"><span class="code-snippet__params">__int64 a1, __int64 a2</span></span><span class="code-snippet__function">)</span></span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf="">lck_rw_lock_exclusive((IORWLock *)blacklistLock);</span></code><br/><code><span leaf=""> IOFree((<span class="code-snippet__keyword">void</span> *)blacklist, <span class="code-snippet__number">32</span> * blacklistSize);</span></code><br/><code><span leaf=""> blacklist = a1;</span></code><br/><code><span leaf=""> blacklistSize = a2;</span></code><br/><code><span leaf="">lck_rw_done((IORWLock *)blacklistLock);</span></code><br/><code><span leaf="">}</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    释放原有</span></span><span lang="EN-US"><span leaf="">blacklist</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">内存，更新</span></span><span lang="EN-US"><span leaf="">blacklist</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">新内存。</span></span></p><p><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf=""><span textstyle="" style="font-size: 18px;font-weight: bold;">3.2.4 用户态查询与设置接口</span></span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">  内核提供了</span></span><span lang="EN-US"><span leaf="">csops_internal</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">函数用于接收用户态参数，对以下进程的签名信息进行设置与读取。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf="">Bsd/sys/codesign.h</span></code><br/><code><span leaf=""><span class="code-snippet__comment">/* csopsoperations */</span></span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">define</span></span><span class="code-snippet__meta"> CS_OPS_STATUS 0       </span><span class="code-snippet__meta"><span class="code-snippet__comment">/* return status */</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">define</span></span><span class="code-snippet__meta"> CS_OPS_MARKINVALID 1      </span><span class="code-snippet__meta"><span class="code-snippet__comment">/* invalidate process */</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">define</span></span><span class="code-snippet__meta"> CS_OPS_MARKHARD 2      </span><span class="code-snippet__meta"><span class="code-snippet__comment">/* set HARD flag */</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">define</span></span><span class="code-snippet__meta"> CS_OPS_MARKKILL 3      </span><span class="code-snippet__meta"><span class="code-snippet__comment">/* set KILL flag (sticky) */</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">ifdef</span></span><span class="code-snippet__meta"> KERNEL_PRIVATE</span></span></code><br/><code><span leaf=""><span class="code-snippet__comment">/* CS_OPS_PIDPATH 4       */</span></span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">endif</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">define</span></span><span class="code-snippet__meta"> CS_OPS_CDHASH 5       </span><span class="code-snippet__meta"><span class="code-snippet__comment">/* get code directory hash */</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">define</span></span><span class="code-snippet__meta"> CS_OPS_PIDOFFSET 6      </span><span class="code-snippet__meta"><span class="code-snippet__comment">/* get offset of active Mach-o slice */</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">define</span></span><span class="code-snippet__meta"> CS_OPS_ENTITLEMENTS_BLOB 7 </span><span class="code-snippet__meta"><span class="code-snippet__comment">/* get entitlements blob */</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">define</span></span><span class="code-snippet__meta"> CS_OPS_MARKRESTRICT 8      </span><span class="code-snippet__meta"><span class="code-snippet__comment">/* set RESTRICT flag (sticky) */</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">define</span></span><span class="code-snippet__meta"> CS_OPS_SET_STATUS 9      </span><span class="code-snippet__meta"><span class="code-snippet__comment">/* set codesign flags */</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">define</span></span><span class="code-snippet__meta"> CS_OPS_BLOB 10      </span><span class="code-snippet__meta"><span class="code-snippet__comment">/* get codesign blob */</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">define</span></span><span class="code-snippet__meta"> CS_OPS_IDENTITY 11     </span><span class="code-snippet__meta"><span class="code-snippet__comment">/* get codesign identity */</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">define</span></span><span class="code-snippet__meta"> CS_OPS_CLEARINSTALLER 12     </span><span class="code-snippet__meta"><span class="code-snippet__comment">/* clear INSTALLER flag */</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">define</span></span><span class="code-snippet__meta"> CS_OPS_CLEARPLATFORM 13 </span><span class="code-snippet__meta"><span class="code-snippet__comment">/* clear platform binary status (DEVELOPMENT-only) */</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">define</span></span><span class="code-snippet__meta"> CS_OPS_TEAMID 14 </span><span class="code-snippet__meta"><span class="code-snippet__comment">/* get team id */</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">define</span></span><span class="code-snippet__meta"> CS_OPS_CLEAR_LV 15 </span><span class="code-snippet__meta"><span class="code-snippet__comment">/* clear the library validation flag */</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">define</span></span><span class="code-snippet__meta"> CS_OPS_DER_ENTITLEMENTS_BLOB 16 </span><span class="code-snippet__meta"><span class="code-snippet__comment">/* get der entitlements blob */</span></span></span></code><br/></pre></p><p><span lang="EN-US"><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">3.3 PPL</span></span></span><span style="mso-bookmark:_Toc2198;"><span lang="ZH" style="font-family:黑体;mso-ascii-font-family:
Arial;mso-hansi-font-family:Arial;mso-fareast-language:ZH;"><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">保护</span></span></span></span></p><p><span style="mso-bookmark:_Toc2198;"><span lang="ZH" style="font-family:黑体;mso-ascii-font-family:
Arial;mso-hansi-font-family:Arial;mso-fareast-language:ZH;"><span leaf=""><span textstyle="" style="font-size: 18px;font-weight: bold;">3.3.1 pmap_cs_cd_register_internal</span></span></span></span></p><p style=""><span lang="EN-US"><span leaf="">    ios</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">将</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">code directory</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;mso-fareast-language:ZH;"><span leaf="">存放到</span></span><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf="">ppl</span></span><span lang="ZH" style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:ZH;"><span leaf="">进行保护。</span></span><span lang="EN-US" style="mso-fareast-language:
ZH;"><span leaf="">ppl</span></span><span lang="ZH" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:
ZH;"><span leaf="">中的服务函数为</span></span><span lang="EN-US"><span leaf="">pmap_cs_cd_register_internal</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">，它的功能是将每个进程的</span></span><span lang="EN-US"><span leaf="">csblob</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">结构体放到</span></span><span lang="EN-US"><span leaf="">ppl</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">中进行保护，同时将其部分内容算</span></span><span lang="EN-US"><span leaf="">sha256</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">哈希，存放于一个特殊的</span></span><span lang="EN-US"><span leaf="">cd</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">结构体中，这个结构体又被红黑树管理起来。</span></span></p><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">    第一个参数为</span></span><span lang="EN-US"><span leaf="">struct cs_blob</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">结构体，第二个参数为</span></span><span lang="EN-US"><span leaf="">struct cs_blob</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">结构体的长度，第三个参数为</span></span><span lang="EN-US"><span leaf="">struct cs_blob</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">结构里的某个</span></span><span lang="EN-US"><span leaf="">offset</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，这个函数将</span></span><span lang="EN-US"><span leaf="">csblob</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">结构体保存在</span></span><span lang="EN-US"><span leaf="">ppl</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">中，</span></span></p><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">    同时计算</span></span><span lang="EN-US"><span leaf="">struct cs_blob</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">从</span></span><span lang="EN-US"><span leaf="">offset</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">开始的</span></span><span lang="EN-US"><span leaf="">hash</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">并存放于</span></span><span lang="EN-US"><span leaf="">ppl</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">中，第四、五个参数功能不详。</span></span></p><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">    由于这个函数非常复杂，只贴出部分关键操作的代码。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="nginx"><code><span leaf=""><span class="code-snippet__attribute">MOV</span> X9, <span class="code-snippet__comment">#0xFFFFFFE000000000</span></span></code><br/><code><span leaf="">CMP X0, X9</span></code><br/><code><span leaf="">B.CC loc_FFFFFFF0097FDA8C ; <span class="code-snippet__attribute">x0</span> &lt; 0xFFFFFFE000000000</span></code><br/><code><span leaf="">TBNZ W8, <span class="code-snippet__comment">#0, loc_FFFFFFF0097FDA8C ; x0 + x1 &lt; x0</span></span></code><br/><code><span leaf="">ADD X9, X20, X21</span></code><br/><code><span leaf="">MOV X8, <span class="code-snippet__comment">#0xFFFFFFFC00000000</span></span></code><br/><code><span leaf="">CMP X9, X8</span></code><br/><code><span leaf="">B.CS loc_FFFFFFF0097FDA8C ; <span class="code-snippet__attribute">x0</span> + x1 &gt; 0xFFFFFFFC00000000</span></code><br/><code><span leaf="">MOV X24, X2</span></code><br/><code><span leaf="">ADDS X8, X2, X21</span></code><br/><code><span leaf="">CSET W10, CS</span></code><br/><code><span leaf="">SUBS X26, X20, X2 ; <span class="code-snippet__attribute">offset</span> = x1 - x2</span></code><br/><code><span leaf="">B.CC loc_FFFFFFF0097FDA9C ; <span class="code-snippet__attribute">offset</span> &lt; <span class="code-snippet__number">0</span></span></code><br/><code><span leaf="">TBNZ W10, <span class="code-snippet__comment">#0, loc_FFFFFFF0097FDA9C ; x0 + x2 &lt; x0</span></span></code><br/><code><span leaf="">CMP X8, X9</span></code><br/><code><span leaf="">B.HI loc_FFFFFFF0097FDA9C ; <span class="code-snippet__attribute">x1</span> + x2 &gt; x1 + x0</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    上述代码对前三个参数做了范围检查。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="apache"><code><span leaf=""><span class="code-snippet__attribute">MOV</span> W8, #<span class="code-snippet__number">0</span>x1FF8</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">CMP</span> X20, X8</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">STR</span> X4,<span class="code-snippet__meta"> [SP,#0xD0+var_B0]</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">B</span>.HI loc_FFFFFFF0097FD3AC ; x1 &gt; <span class="code-snippet__number">0</span>x1ff8 x23 = <span class="code-snippet__number">0</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">CMP</span> X20, #<span class="code-snippet__number">0</span>x1F9</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">B</span>.CC loc_FFFFFFF0097FD3B4 ; x1 &lt; <span class="code-snippet__number">0</span>x1f9 x8 = <span class="code-snippet__number">0</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">CMP</span> X20, #<span class="code-snippet__number">0</span>x3F9 ; x1 &lt; <span class="code-snippet__number">0</span>x3f9 x8 = <span class="code-snippet__number">1</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">B</span>.CC loc_FFFFFFF0097FD3BC</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">CMP</span> X20, #<span class="code-snippet__number">0</span>x7F9</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">B</span>.CC loc_FFFFFFF0097FD3C4 ; x1 &lt; <span class="code-snippet__number">0</span>x7f9 x8 = <span class="code-snippet__number">2</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">CMP</span> X20, #<span class="code-snippet__number">0</span>xFF8</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOV</span> W8, #<span class="code-snippet__number">3</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">CINC</span> W8, W8, HI</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">B</span> loc_FFFFFFF0097FD3C8 ; if x1 &lt; <span class="code-snippet__number">0</span>xff8</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">x8</span> = <span class="code-snippet__number">3</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">else</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">x8</span> = <span class="code-snippet__number">4</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOV</span> X23, #<span class="code-snippet__number">0</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">B</span> loc_FFFFFFF0097FD4B8</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOV</span> W8, #<span class="code-snippet__number">0</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">B</span> loc_FFFFFFF0097FD3C8</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOV</span> W8, #<span class="code-snippet__number">1</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">B</span> loc_FFFFFFF0097FD3C8</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOV</span> W8, #<span class="code-snippet__number">2</span></span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    根据第</span></span><span lang="EN-US"><span leaf="">2</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">个参数计算出一个</span></span><span lang="EN-US"><span leaf="">index</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，它是</span></span><span lang="EN-US"><span leaf="">struct csblob _pmap_cs_blob_free_list[]</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">数组的一个索引。在</span></span><span lang="EN-US"><span leaf="">xnu</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">的源码</span></span><span lang="EN-US"><span leaf="">bsd/sys/ubc_internal.h</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">中可以看到</span></span><span lang="EN-US"><span leaf="">struct csblob</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">根据</span></span><span lang="EN-US"><span leaf="">config</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">的不同，</span></span></p><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">有不同的大小。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="perl"><code><span leaf="">MOV W22, W8</span></code><br/><code><span leaf="">LSL X27, X22, <span class="code-snippet__comment">#3 ; index = w8 * 8</span></span></code><br/><code><span leaf="">ADR X25, _pmap_cs_blob_free_list_lock</span></code><br/><code><span leaf="">NOP</span></code><br/><code><span leaf="">MOV X0, X25</span></code><br/><code><span leaf="">BL _hw_lock_lock_nopreempt</span></code><br/><code><span leaf="">ADR X8, _pmap_cs_blob_free_list ; uint64_t _pmap_cs_blob_free_list[]</span></code><br/><code><span leaf="">NOP</span></code><br/><code><span leaf="">LDR X23, [X8,X27] ; csblob_struct =_pmap_cs_blob_free_list[<span class="code-snippet__keyword">index</span>]</span></code><br/><code><span leaf="">CBZ X23, loc_FFFFFFF0097FD428</span></code><br/><code><span leaf="">LDR X9, [X23] ; <span class="code-snippet__keyword">next</span> = csblob_struct-&gt;<span class="code-snippet__keyword">next</span></span></code><br/><code><span leaf="">STR X9, [X8,X22,LSL<span class="code-snippet__comment">#3] ; _pmap_cs_blob_free_list[index]=next</span></span></code><br/><code><span leaf="">STR X19, [X23] ; csblob_struct-&gt;<span class="code-snippet__keyword">next</span>=<span class="code-snippet__number">0xDEADEAD0A110CED</span></span></code><br/><code><span leaf="">LSL X8, X22, <span class="code-snippet__comment">#2 ; index1=w8 * 4</span></span></code><br/><code><span leaf="">ADR X9, _pmap_cs_blob_free_count</span></code><br/><code><span leaf="">NOP</span></code><br/><code><span leaf="">LDR W10, [X9,X8]</span></code><br/><code><span leaf="">SUB W10, W10, <span class="code-snippet__comment">#1</span></span></code><br/><code><span leaf="">STR W10, [X9,X8] ; _pmap_cs_blob_free_count[index1] -= <span class="code-snippet__number">1</span></span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">  根据</span></span><span lang="EN-US"><span leaf="">index</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，从</span></span><span lang="EN-US"><span leaf="">_pmap_cs_blob_free_list</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">找到一个空闲的块，</span></span><span lang="EN-US"><span leaf=""> pmap_cs_blob_free_count</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">数组保存的是对应的</span></span><span lang="EN-US"><span leaf="">cs_blob</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">大小的空闲数目。</span></span></p><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">  如果</span></span><span lang="EN-US"><span leaf="">_pmap_cs_blob_free_list</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">对应的节点为空，则要申请一个新的</span></span><span lang="EN-US"><span leaf="">page</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="apache"><code><span leaf=""><span class="code-snippet__attribute">MRS</span> X8, #<span class="code-snippet__number">0</span>, c13, c0, #<span class="code-snippet__number">4</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">LDR</span> W8,<span class="code-snippet__meta"> [X8,#0x500]</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">CBZ</span> W8, loc_FFFFFFF0097FDB14</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">STLR</span> XZR,<span class="code-snippet__meta"> [X25]</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">BL</span> _pmap_get_free_ppl_page</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">CBZ</span> X0, loc_FFFFFFF0097FD900</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOV</span> X23, X0 ; new_blob_page</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">ADRL</span> X8, _pmap_cs_blob_bins</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">LDR</span> X25,<span class="code-snippet__meta"> [X8,X27] ; bin_size = _pmap_cs_blob_bins[index]</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">BL</span> _phystokv</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOV</span> W27, #<span class="code-snippet__number">0</span>x4000</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOV</span> W1, #<span class="code-snippet__number">0</span>x4000 ; size_t</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">BL</span> _bzero  ; bzero(new_blog_page, <span class="code-snippet__number">0</span>x4000)</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOV</span> X0, X23</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">BL</span> _phystokv</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOV</span> X23, X0</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOV</span> X1, #<span class="code-snippet__number">0</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOV</span> X11, #<span class="code-snippet__number">0</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">STR</span> X19,<span class="code-snippet__meta"> [X0] ; ((csblob_struct *)new_blob_page)-&gt;next = 0xDEADEAD0A110CED</span></span></code><br/><code><span leaf="">AND X8, X25, <a class="wx_topic_link" topic-id="mjxki4n4-yka077" style="color: #576B95 !important;" data-topic="1">#0xFFFFFFFFFFFFFFF8</a> ; bin_size &amp;= 0xFFFFFFFFFFFFFFF8</span></code><br/><code><span leaf="">MOV W9, <a class="wx_topic_link" topic-id="mjxki4n4-1j6mkk" style="color: #576B95 !important;" data-topic="1">#2</a>  ; x9 = 2</span></code><br/><code><span leaf="">UDIV X10, X27, X25 ; num = 0x4000 / bin_size</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    _pmap_get_free_ppl_page</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">从</span></span><span lang="EN-US"><span leaf="">ppl</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">中申请了一个新的物理页，通过</span></span><span lang="EN-US"><span leaf="">_phystokv</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">转化为虚拟地址，然后用</span></span><span lang="EN-US"><span leaf="">bzero</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">进行初始化。前面将</span></span><span lang="EN-US"><span leaf="">csblob</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">有不同的大小，对一个新分配好的</span></span><span lang="EN-US"><span leaf="">page</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">要对它进行切块分配，自然要知道每个块的大小，</span></span><span lang="EN-US"><span leaf="">_pmap_cs_blob_bins</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">数组保存的就是对应的</span></span><span lang="EN-US"><span leaf="">csblob</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">大小。最后</span></span><span lang="EN-US"><span leaf="">x10</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">保存的是一个</span></span><span lang="EN-US"><span leaf="">page</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">对应的</span></span><span lang="EN-US"><span leaf="">csblob</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">块大小，然后通过一个循环对其进行初始化。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="perl"><code><span leaf="">ADD X0, X0, X8 ; current_page = new_blob_page</span></code><br/><code><span leaf=""> ; next_page = <span class="code-snippet__number">0</span></span></code><br/><code><span leaf=""> ; <span class="code-snippet__keyword">do</span> {</span></code><br/><code><span leaf=""> ; current_page += bin_size</span></code><br/><code><span leaf="">STR X11, [X0] ; *(current_page-&gt;<span class="code-snippet__keyword">next</span>) = next_page</span></code><br/><code><span leaf="">CMP X1, <span class="code-snippet__comment">#0</span></span></code><br/><code><span leaf="">CSEL X1, X0, X1, EQ ; <span class="code-snippet__keyword">if</span> (x1 == <span class="code-snippet__number">0</span>)</span></code><br/><code><span leaf="">x1 = x0</span></code><br/><code><span leaf="">ADD W12, W9, <span class="code-snippet__comment">#1</span></span></code><br/><code><span leaf="">CMP X10, W9,UXTW</span></code><br/><code><span leaf="">MOV X9, X12 ; x9 += <span class="code-snippet__number">1</span></span></code><br/><code><span leaf="">MOV X11, X0 ; next_page = current_page</span></code><br/><code><span leaf="">B.HI loc_FFFFFFF0097FD484 ; <span class="code-snippet__keyword">while</span> (num &gt; x9)</span></code><br/><code><span leaf="">SUB W3, W12, <span class="code-snippet__comment">#2 ; num -= 2</span></span></code><br/><code><span leaf="">MOV X2, X22 ; <span class="code-snippet__keyword">index</span></span></code><br/><code><span leaf="">MOV W4, <span class="code-snippet__comment">#1</span></span></code><br/><code><span leaf="">BL _pmap_cs_blob_add_to_free_list</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    这个循环是对每个</span></span><span lang="EN-US"><span leaf="">csblob</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">的第一个成员，也就是</span></span><span lang="EN-US"><span leaf="">next</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">指针进行初始化，注意每个</span></span><span lang="EN-US"><span leaf="">page</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">的第一个</span></span><span lang="EN-US"><span leaf="">csblob</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">是保留不用的，没有被链接起来，它的</span></span><span lang="EN-US"><span leaf="">next</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">是指向</span></span><span lang="EN-US"><span leaf="">0xDEADEAD0A110CED</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。</span></span></p><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">  最后通过</span></span><span lang="EN-US"><span leaf="">_pmap_cs_blob_add_to_free_list</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">把这些块加入到现有链表中。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf=""><span class="code-snippet__function">__int64 __fastcall </span><span class="code-snippet__function"><span class="code-snippet__title">pmap_cs_blob_add_to_free_list</span></span><span class="code-snippet__function"><span class="code-snippet__params">(</span></span><span class="code-snippet__function"><span class="code-snippet__params"><span class="code-snippet__type">void</span></span></span><span class="code-snippet__function"><span class="code-snippet__params"> *a1, _QWORD *a2, __int64 a3, __int64 a4, __int64 a5)</span></span></span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""> v7 = pmap_cs_blob_bins[(<span class="code-snippet__type">unsigned</span> <span class="code-snippet__type">int</span>)a3];</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> ( ((<span class="code-snippet__type">unsigned</span> __int16)a1 &amp; <span class="code-snippet__number">0x3FFFu</span>) % v7 || ((<span class="code-snippet__type">unsigned</span> __int16)a2 &amp; <span class="code-snippet__number">0x3FFFu</span>) % v7 )</span></code><br/><code><span leaf=""><span class="code-snippet__built_in">panic</span>(<span class="code-snippet__string">&#34;\&#34;free blob to add unaligned: (%p,%p)/%zu\&#34;&#34;</span>, a1, a2, v7);</span></code><br/><code><span leaf=""> v11 = (<span class="code-snippet__type">unsigned</span> <span class="code-snippet__type">int</span>)a3;</span></code><br/><code><span leaf="">result = <span class="code-snippet__built_in">hw_lock_lock_nopreempt</span>(&amp;pmap_cs_blob_free_list_lock);</span></code><br/><code><span leaf=""> *a2 = *(&amp;pmap_cs_blob_free_list + v11);</span></code><br/><code><span leaf="">*(&amp;pmap_cs_blob_free_list + v11) = a1;</span></code><br/><code><span leaf=""> v13 = pmap_cs_blob_free_count[v11];</span></code><br/><code><span leaf="">pmap_cs_blob_free_count[v11] = v13 + a4;</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">if</span> ( __CFADD__(v13, (_DWORD)a4) )</span></code><br/><code><span leaf=""><span class="code-snippet__built_in">panic</span>(<span class="code-snippet__string">&#34;\&#34;blob free count overflow (bin %d, %d/%d)\&#34;&#34;</span>, a3, (<span class="code-snippet__type">unsigned</span> <span class="code-snippet__type">int</span>)pmap_cs_blob_free_count[v11], a4);</span></code><br/><code><span leaf=""> v14 = pmap_cs_blob_page_count[v11];</span></code><br/><code><span leaf="">pmap_cs_blob_page_count[v11] = v14 + a5;</span></code><br/><code><span leaf="">}</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    上述代码将链表头链接到新</span></span><span lang="EN-US"><span leaf="">page</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">的最有一个块，然后更新对应的</span></span><span lang="EN-US"><span leaf="">free</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">节点数目。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="apache"><code><span leaf=""><span class="code-snippet__attribute">MRS</span> X8, #<span class="code-snippet__number">0</span>, c13, c0, #<span class="code-snippet__number">4</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">LDR</span> W8,<span class="code-snippet__meta"> [X8,#0x500]</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">CBZ</span> W8, loc_FFFFFFF0097FDAC4</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">STLR</span> XZR,<span class="code-snippet__meta"> [X25]</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOV</span> W8, #<span class="code-snippet__number">0</span>x1FF9</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">CMP</span> X20, X8</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">B</span>.CS loc_FFFFFFF0097FD5E4 ; x1 &gt; <span class="code-snippet__number">0</span>x1ff9</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">ADD</span> X25, X23, #<span class="code-snippet__number">8</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOV</span> X0, X25 ; __dst</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOV</span> X1, X21 ; __src</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOV</span> X2, X20 ; __n</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">BL</span> _memmove ; memmove(new_blog_page + <span class="code-snippet__number">8</span>, x0, x1)</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    使用</span></span><span lang="EN-US"><span leaf="">memove</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">将第一个参数指向的</span></span><span lang="EN-US"><span leaf="">csblob</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">结构体拷贝到刚申请到内存块中。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="ruby"><code><span leaf=""><span class="code-snippet__variable">ADR</span> <span class="code-snippet__variable">X25</span>, _pmap_cs_cd_free_list_lock</span></code><br/><code><span leaf=""><span class="code-snippet__variable">NOP</span></span></code><br/><code><span leaf=""><span class="code-snippet__variable">MOV</span> <span class="code-snippet__variable">X0</span>, <span class="code-snippet__variable">X25</span></span></code><br/><code><span leaf=""><span class="code-snippet__variable">BL</span> _hw_lock_lock_nopreempt</span></code><br/><code><span leaf=""><span class="code-snippet__variable">ADRP</span> <span class="code-snippet__variable">X22</span>, <span class="code-snippet__comment">#_pmap_cs_cd_free_list</span><span class="code-snippet__comment"><span class="code-snippet__doctag">@PAGE</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__variable">LDR</span> <span class="code-snippet__variable">X28</span>, [<span class="code-snippet__variable">X22</span>,<span class="code-snippet__comment">#_pmap_cs_cd_free_list</span><span class="code-snippet__comment"><span class="code-snippet__doctag">@PAGEOFF</span></span><span class="code-snippet__comment">]</span></span></code><br/><code><span leaf=""><span class="code-snippet__variable">ADRP</span> <span class="code-snippet__variable">X27</span>, <span class="code-snippet__comment">#_pmap_cs_cd_free_count</span><span class="code-snippet__comment"><span class="code-snippet__doctag">@PAGE</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__variable">CBZ</span> <span class="code-snippet__variable">X28</span>, loc_FFFFFFF0097FD4F4 ; _pmap_cs_cd_free_list == <span class="code-snippet__number">0</span></span></code><br/><code><span leaf=""><span class="code-snippet__variable">LDR</span> <span class="code-snippet__variable">X8</span>, [<span class="code-snippet__variable">X28</span>] ; <span class="code-snippet__keyword">next</span> = *pmap_cs_cd_free_list</span></code><br/><code><span leaf=""><span class="code-snippet__variable">STR</span> <span class="code-snippet__variable">X8</span>, [<span class="code-snippet__variable">X22</span>,<span class="code-snippet__comment">#_pmap_cs_cd_free_list</span><span class="code-snippet__comment"><span class="code-snippet__doctag">@PAGEOFF</span></span><span class="code-snippet__comment">] ; pmap_cs_cd_free_list = next</span></span></code><br/><code><span leaf=""><span class="code-snippet__variable">STR</span> <span class="code-snippet__variable">X19</span>, [<span class="code-snippet__variable">X28</span>] ; *<span class="code-snippet__keyword">next</span> = <span class="code-snippet__number">0xDEADEAD0A110CED</span></span></code><br/><code><span leaf=""><span class="code-snippet__variable">LDR</span> <span class="code-snippet__variable">W8</span>, [<span class="code-snippet__variable">X27</span>,<span class="code-snippet__comment">#_pmap_cs_cd_free_count</span><span class="code-snippet__comment"><span class="code-snippet__doctag">@PAGEOFF</span></span><span class="code-snippet__comment">]</span></span></code><br/><code><span leaf=""><span class="code-snippet__variable">SUB</span> <span class="code-snippet__variable">W8</span>, <span class="code-snippet__variable">W8</span>, <span class="code-snippet__comment">#1</span></span></code><br/><code><span leaf=""><span class="code-snippet__variable">STR</span>  <span class="code-snippet__variable">W8</span>, [<span class="code-snippet__variable">X27</span>,<span class="code-snippet__comment">#_pmap_cs_cd_free_count</span><span class="code-snippet__comment"><span class="code-snippet__doctag">@PAGEOFF</span></span><span class="code-snippet__comment">] ; _pmap_cs_cd_free_count[index] -= 1</span></span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    在获取一个</span></span><span lang="EN-US"><span leaf="">csblob</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">结构体后，接着要从</span></span><span lang="EN-US"><span leaf="">_pmap_cs_cd_free_list</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">链表分配一个</span></span><span lang="EN-US"><span leaf="">cd</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">结构体，注意它是不同于</span></span><span lang="EN-US"><span leaf="">struct __CodeDirectory</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，是</span></span><span lang="EN-US"><span leaf="">ppl</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">内部使用的一个结构体。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="apache"><code><span leaf=""><span class="code-snippet__attribute">MRS</span> X8, #<span class="code-snippet__number">0</span>, c13, c0, #<span class="code-snippet__number">4</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">LDR</span> W8,<span class="code-snippet__meta"> [X8,#0x500]</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">CBZ</span> W8, loc_FFFFFFF0097FDADC</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">STLR</span> XZR,<span class="code-snippet__meta"> [X25]</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">BL</span> _pmap_get_free_ppl_page</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">CBZ</span> X0, loc_FFFFFFF0097FD648</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOV</span> X22, X0 ; new_cd_page</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">BL</span> _phystokv</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOV</span> W1, #<span class="code-snippet__number">0</span>x4000 ; size_t</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">BL</span> _bzero  ; bzero(new_cd_page, <span class="code-snippet__number">0</span>x4000)</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOV</span> X0, X22</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">BL</span> _phystokv</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOV</span> X28, X0</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOV</span> X27, #<span class="code-snippet__number">0</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOV</span> X9, #<span class="code-snippet__number">0</span>  ; next_page = <span class="code-snippet__number">0</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOV</span> X22, X0 ; current_page = new_cd_page</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">STR</span> X19,<span class="code-snippet__meta"> [X22],#0x70 ; ((cscd_struct *)current_page)-&gt;next = 0xDEADEAD0A110CED</span></span></code><br/><code><span leaf="">__PPLTEXT:__text:FFFFFFF0097FD534 ; current_page += 0x70</span></code><br/><code><span leaf="">MOV W8, <a class="wx_topic_link" topic-id="mjxki4n4-9b19ly" style="color: #576B95 !important;" data-topic="1">#0x91</a></span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    如果</span></span><span lang="EN-US"><span leaf="">_pmap_cs_cd_free_list</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">为空，则调用</span></span><span lang="EN-US"><span leaf="">_pmap_get_free_ppl_page</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">申请一个新的物理页，对其进行初始化，可以看到每个</span></span><span lang="EN-US"><span leaf="">cd</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">结构体的大小为</span></span><span lang="EN-US"><span leaf="">0x91</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="nginx"><code><span leaf=""><span class="code-snippet__attribute">MOV</span> X10, X22 ; <span class="code-snippet__attribute">tmp_page</span> = current_page</span></code><br/><code><span leaf="">STR X9, [X22],<span class="code-snippet__comment">#0x70 ; *(current_page-&gt;next) = next_page</span></span></code><br/><code><span leaf="">current_page += 0x70</span></code><br/><code><span leaf="">CMP X27, <span class="code-snippet__comment">#0</span></span></code><br/><code><span leaf="">CSEL X27, X10, X27, EQ ; <span class="code-snippet__attribute">if</span> (x27 == <span class="code-snippet__number">0</span>)</span></code><br/><code><span leaf="">first_page = tmp_page</span></code><br/><code><span leaf="">MOV X9, X10 ; <span class="code-snippet__attribute">next_page</span> = current_page</span></code><br/><code><span leaf="">SUBS W8, W8, <span class="code-snippet__comment">#1 ; w8 -= 1</span></span></code><br/><code><span leaf="">B.NE loc_FFFFFFF0097FD53C ; <span class="code-snippet__attribute">while</span> (w8 != <span class="code-snippet__number">0</span>)</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    循环对每个</span></span><span lang="EN-US"><span leaf="">cd</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">的</span></span><span lang="EN-US"><span leaf="">next</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">字段进行设置，同样第一个</span></span><span lang="EN-US"><span leaf="">cd</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">是保留不用的，</span></span><span lang="EN-US"><span leaf="">next</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">字段设置为</span></span><span lang="EN-US"><span leaf="">0xDEADEAD0A110CED</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="powershell"><code><span leaf="">MOV X2, X25 ; size</span></code><br/><code><span leaf="">MOV X3, X24</span></code><br/><code><span leaf="">BL _hash</span></code><br/><code><span leaf="">ADD X0, <span class="code-snippet__built_in">SP</span>, <span class="code-snippet__comment">#0xD0+__dst ; __dst</span></span></code><br/><code><span leaf="">ADD X1, <span class="code-snippet__built_in">SP</span>, <span class="code-snippet__comment">#0xD0+__src ; __src</span></span></code><br/><code><span leaf="">MOV W2, <span class="code-snippet__comment">#0x14 ; __n</span></span></code><br/><code><span leaf="">BL _memmove ; memmove(new_hash, x1, <span class="code-snippet__number">0</span>x14)</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    从</span></span><span lang="EN-US"><span leaf="">csblob</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">结构体的第</span></span><span lang="EN-US"><span leaf="">2</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">个参数起始位置算</span></span><span lang="EN-US"><span leaf="">hash</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">值。如果这个</span></span><span lang="EN-US"><span leaf="">hash</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">值在静态</span></span><span lang="EN-US"><span leaf="">trustcache</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">或动态</span></span><span lang="EN-US"><span leaf="">trustcache</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">中，</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">还要做进一步合法性检查。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cs"><code><span leaf="">STP WZR, W19, [X28,<span class="code-snippet__meta">#0x50] ; *(new_cd_page + 0x50) = 0</span></span></code><br/><code><span leaf="">*(new_cd_page + <span class="code-snippet__number">0x58</span>) = flag</span></code><br/><code><span leaf="">MOV W8, <span class="code-snippet__meta">#0x11</span></span></code><br/><code><span leaf="">STR X8, [X28,<span class="code-snippet__meta">#0x48] ; *(new_cd_page + 0x11) = 0x11</span></span></code><br/><code><span leaf="">STR XZR, [X28,<span class="code-snippet__meta">#0x40] ; *(new_cd_page + 0x40) = 0</span></span></code><br/><code><span leaf="">ADD X0, X28, <span class="code-snippet__meta">#0x5C ; &#39;\&#39; ; __dst</span></span></code><br/><code><span leaf="">STR W26, [X28,<span class="code-snippet__meta">#0x58]</span></span></code><br/><code><span leaf="">ADD X1, SP, <span class="code-snippet__meta">#0xD0+__dst ; __src</span></span></code><br/><code><span leaf="">MOV W2, <span class="code-snippet__meta">#0x14 ; __n</span></span></code><br/><code><span leaf="">BL _memmove ; memmove(new_cd_page + <span class="code-snippet__number">0x5c</span>, new_hash, <span class="code-snippet__number">20</span>)</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    将算出来的</span></span><span lang="EN-US"><span leaf="">hash</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">值保存在</span></span><span lang="EN-US"><span leaf="">cd</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">结构体的</span></span><span lang="EN-US"><span leaf="">0x5c</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">处。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="nginx"><code><span leaf=""><span class="code-snippet__attribute">ADR</span> X8, _pmap_cs_registered_cds</span></code><br/><code><span leaf="">NOP</span></code><br/><code><span leaf="">STR X28, [X8] ; <span class="code-snippet__attribute">_pmap_cs_registered_cds</span> = new_cd_page</span></code><br/><code><span leaf="">ADR X0, _pmap_cs_registered_cds</span></code><br/><code><span leaf="">NOP</span></code><br/><code><span leaf="">MOV X1, X28</span></code><br/><code><span leaf="">BL_pmap_cs_code_directories_RB_INSERT_COLOR</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    _pmap_cs_registered_cds</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">变量保存的是</span></span><span lang="EN-US"><span leaf="">cd</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">结构体的红黑树，如果它为空，直接将</span></span><span lang="EN-US"><span leaf="">cd</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">结构体设为</span></span><span lang="EN-US"><span leaf="">root</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">节点，否则调用</span></span><span lang="EN-US"><span leaf="">_pmap_cs_code_directories_RB_INSERT_COLOR</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">将其插入到红黑树中。</span></span></p><p style=""><span style="mso-bookmark:_Toc10223;"><span lang="ZH" style="font-size:
16.0pt;mso-bidi-font-size:12.0pt;font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-fareast-language:
ZH;"><span leaf=""><span textstyle="" style="font-size: 18px;font-weight: bold;">3.3.2 zalloc只读内存保护</span></span></span></span></p><h4><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf=""><span textstyle="" style="font-weight: bold;">3.3.2.1 </span></span></span><span lang="EN-US"><span leaf=""><span textstyle="" style="font-weight: bold;">zalloc_ro_mut</span></span></span></h4><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf="">__attribute__((noinline))</span></code><br/><code><span leaf=""><span class="code-snippet__function"><span class="code-snippet__type">void</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__title">zalloc_ro_mut</span><span class="code-snippet__params">(</span><span class="code-snippet__params"><span class="code-snippet__type">zone_id_t</span></span><span class="code-snippet__params"> zid, </span><span class="code-snippet__params"><span class="code-snippet__type">void</span></span><span class="code-snippet__params"> *elem, </span><span class="code-snippet__params"><span class="code-snippet__type">vm_offset_t</span></span><span class="code-snippet__params"> offset,</span></span></code><br/><code><span leaf=""><span class="code-snippet__type">const</span> <span class="code-snippet__type">void</span> *new_data, <span class="code-snippet__type">vm_size_t</span> new_data_size)</span></code><br/><code><span leaf="">{ </span></code><br/><code><span leaf=""><span class="code-snippet__built_in">zalloc_ro_mut_validate_src</span>(zid, elem, (<span class="code-snippet__type">vm_offset_t</span>)new_data,</span></code><br/><code><span leaf="">     new_data_size);</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">pmap_ro_zone_memcpy</span>(zid, (<span class="code-snippet__type">vm_offset_t</span>) elem, offset,</span></code><br/><code><span leaf="">     (<span class="code-snippet__type">vm_offset_t</span>) new_data, new_data_size);</span></code><br/><code><span leaf="">}</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">  zalloc_ro_mut</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">函数用于将指定内存拷贝到只读内存，</span></span><span lang="EN-US"><span leaf="">pmap_ro_zone_memcpy</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">函数请求的是</span></span><span lang="EN-US"><span leaf="">ppl</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">中对应的服务函数，</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">我们以最新的</span></span><span lang="EN-US"><span leaf="">ios16</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">为例进行逆向分析。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="nginx"><code><span leaf=""><span class="code-snippet__attribute">pmap_ro_zone_memcpy_ppl</span> ; <span class="code-snippet__attribute">DATA</span> XREF:</span></code><br/><code><span leaf="">MOV X20, X4</span></code><br/><code><span leaf="">MOV X22, X3</span></code><br/><code><span leaf="">MOV X23, X2</span></code><br/><code><span leaf="">MOV X21, X1</span></code><br/><code><span leaf="">MOV X25, X0</span></code><br/><code><span leaf="">ADD X24, X2, X1</span></code><br/><code><span leaf="">MOV X0, X24 ; <span class="code-snippet__attribute">va</span> + offset</span></code><br/><code><span leaf="">BL kvtophys_nofail</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    首先调用</span></span><span lang="EN-US"><span leaf="">kvtophys_nofail</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">将</span></span><span lang="EN-US"><span leaf="">va + offset</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">转为物理地址</span></span><span lang="EN-US"><span leaf="">pa</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="ruby"><code><span leaf=""><span class="code-snippet__variable">MOV</span>             <span class="code-snippet__variable">X19</span>, <span class="code-snippet__variable">X0</span> ; pa</span></code><br/><code><span leaf=""><span class="code-snippet__variable">ADRP</span> <span class="code-snippet__variable">X8</span>, <span class="code-snippet__comment">#vm_first_phys</span><span class="code-snippet__comment"><span class="code-snippet__doctag">@PAGE</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__variable">LDR</span> <span class="code-snippet__variable">X8</span>, [<span class="code-snippet__variable">X8</span>,<span class="code-snippet__comment">#vm_first_phys</span><span class="code-snippet__comment"><span class="code-snippet__doctag">@PAGEOFF</span></span><span class="code-snippet__comment">]</span></span></code><br/><code><span leaf=""><span class="code-snippet__variable">ADRP</span> <span class="code-snippet__variable">X9</span>, <span class="code-snippet__comment">#vm_last_phys</span><span class="code-snippet__comment"><span class="code-snippet__doctag">@PAGE</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__variable">LDR</span> <span class="code-snippet__variable">X9</span>, [<span class="code-snippet__variable">X9</span>,<span class="code-snippet__comment">#vm_last_phys</span><span class="code-snippet__comment"><span class="code-snippet__doctag">@PAGEOFF</span></span><span class="code-snippet__comment">]</span></span></code><br/><code><span leaf=""><span class="code-snippet__variable">CMP</span> <span class="code-snippet__variable">X8</span>, <span class="code-snippet__variable">X0</span></span></code><br/><code><span leaf=""><span class="code-snippet__variable">CCMP</span> <span class="code-snippet__variable">X9</span>, <span class="code-snippet__variable">X0</span>, <span class="code-snippet__comment">#0, LS</span></span></code><br/><code><span leaf="">B.<span class="code-snippet__variable">LS</span> loc_FFFFFFF008498A94 ; vm_first_phys &lt; pa &lt; vm_last_phys</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    接着判断物理地址</span></span><span lang="EN-US"><span leaf="">pa</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">是否在合法地址范围内。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="nginx"><code><span leaf=""><span class="code-snippet__attribute">CBZ</span> X22, loc_FFFFFFF008498A78 ; <span class="code-snippet__attribute">new_data</span> == NULL</span></code><br/><code><span leaf="">CBZ X20, loc_FFFFFFF008498A78 ; <span class="code-snippet__attribute">new_data_size</span> == <span class="code-snippet__number">0</span></span></code><br/></pre></p><p><span lang="EN-US"><span style="background:yellow;mso-highlight:yellow;"><span leaf="">    判断</span></span></span><span lang="EN-US"><span leaf="">new_data</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">是否为空，</span></span><span lang="EN-US"><span leaf=""> new_data_size</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">是否为</span></span><span lang="EN-US"><span leaf="">0</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="css"><code><span leaf="">MOV X0, X25</span></code><br/><code><span leaf="">MOV X1, X21</span></code><br/><code><span leaf="">MOV X2, X23</span></code><br/><code><span leaf="">MOV X3, X22</span></code><br/><code><span leaf="">MOV X4, X20</span></code><br/><code><span leaf="">BL pmap_ro_zone_validate_element ; (zid, va, <span class="code-snippet__attribute">offset</span>, new_data, new_data_size)</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    调用</span></span><span lang="EN-US"><span leaf="">pmap_ro_zone_validate_element</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">函数做参数检查，在稍后会详细分析。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf="">MOV X0, X19</span></code><br/><code><span leaf="">MOV X1, X21</span></code><br/><code><span leaf="">MOV X2, X20</span></code><br/><code><span leaf="">BL pmap_ro_zone_lock_phy_page ; (pa, va, offset)</span></code><br/><code><span leaf="">MOV X0, X19 ; <span class="code-snippet__type">vm_offset_t</span></span></code><br/><code><span leaf="">BL _ml_static_ptovirt_0</span></code><br/><code><span leaf="">MOV X1, X22 ; __src</span></code><br/><code><span leaf="">MOV X2, X20 ; __n</span></code><br/><code><span leaf="">BL _memmove ; (pa, new_data, new_data, size)</span></code><br/></pre></p><p><span lang="EN-US"><span style="background:yellow;mso-highlight:yellow;"><span leaf="">    可以看到，</span></span></span><span lang="EN-US"><span leaf="">ppl</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">直接使用</span></span><span lang="EN-US"><span leaf="">memmove</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">将目标内存拷贝进</span></span><span lang="EN-US"><span leaf="">va</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">对应的物理内存。</span></span><span lang="EN-US"><span leaf="">Ppl</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">并没有做请求来源的验证，这导致攻击者可以利用</span></span><span lang="EN-US"><span leaf="">rop</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">等技术直接调用此服务函数，将</span></span><span lang="EN-US"><span leaf="">readonly</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">内存改写为其他的内容。</span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">接着，</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">我们在仔细分析</span></span><span lang="EN-US"><span leaf="">pmap_ro_zone_validate_element</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">函数。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="css"><code><span leaf="">pmap_ro_zone_validate_element ; <span class="code-snippet__selector-tag">CODE</span> XREF: pmap_ro_zone_bzero_ppl+<span class="code-snippet__number">6</span>C↑p</span></code><br/><code><span leaf="">ADDS X8, X3, X4</span></code><br/><code><span leaf="">B.CS loc_FFFFFFF0084946E0 ; new_data + new_data_size &lt; new_data</span></code><br/><code><span leaf="">MOV X3, X4</span></code><br/><code><span leaf=""><span class="code-snippet__selector-tag">B</span> pmap_ro_zone_validate_element_dst ; (zid, va, <span class="code-snippet__attribute">offset</span>, new_data_size)</span></code><br/></pre></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">    首先判断</span></span><span lang="EN-US"><span leaf="">new_data + new_data_size</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">是否溢出，然后调用</span></span><span lang="EN-US"><span leaf="">pmap_ro_zone_validate_element_dst</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="nginx"><code><span leaf=""><span class="code-snippet__attribute">pmap_ro_zone_validate_element_dst</span> ; <span class="code-snippet__attribute">CODE</span> XREF:</span></code><br/><code><span leaf="">ADRL X9, zone_ro_elem_size</span></code><br/><code><span leaf="">ADD X8, X9, W0,UXTW<span class="code-snippet__comment">#3</span></span></code><br/><code><span leaf="">LDR W8, [X8,<span class="code-snippet__comment">#4] ; elem_size = zone_ro_elem_size[zid]</span></span></code><br/><code><span leaf="">ADRL X10, zone_info.zi_ro_range</span></code><br/><code><span leaf="">ADD X11, X10, <span class="code-snippet__comment">#8</span></span></code><br/><code><span leaf="">LDP X10, X11, [X10] ; <span class="code-snippet__attribute">x10</span> = start</span></code><br/><code><span leaf=""> ; <span class="code-snippet__attribute">x11</span> = end</span></code><br/><code><span leaf="">CMP X10, X1</span></code><br/><code><span leaf="">CCMP X11, X1, <span class="code-snippet__comment">#0, LS</span></span></code><br/><code><span leaf="">B.LS            loc_FFFFFFF008494928 ; <span class="code-snippet__attribute">x10</span> &lt; va &lt; x11</span></code><br/></pre></p><p style="margin-left: 0cm;"><span lang="EN-US"><span style="background:yellow;mso-highlight:yellow;"><span leaf="">    判断</span></span></span><span lang="EN-US"><span leaf="">va</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">是否在合法地址范围内，</span></span><span lang="EN-US"><span leaf="">Readonly</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">内存是从</span></span><span lang="EN-US"><span leaf="">zone_info.zi_ro_range</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">专有内存块分配的。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="nginx"><code><span leaf=""><span class="code-snippet__attribute">MOV</span> W10, W0</span></code><br/><code><span leaf="">LSL X10, X10, <span class="code-snippet__comment">#3</span></span></code><br/><code><span leaf="">LDR W9, [X9,X10] ; <span class="code-snippet__attribute">elem_size1</span> = zone_ro_elem_size[zid &lt;&lt; <span class="code-snippet__number">3</span>]</span></code><br/><code><span leaf="">AND W10, W1, <span class="code-snippet__comment">#0x3FFF ; va &amp;= 0x3fff</span></span></code><br/><code><span leaf="">MOV W11, <span class="code-snippet__comment">#0x4000</span></span></code><br/><code><span leaf="">SUB W10, W11, W10 ; <span class="code-snippet__attribute">va</span> = 0x4000 - va</span></code><br/><code><span leaf="">MUL W10, W9, W10 ; <span class="code-snippet__attribute">va</span> *= elem_size1</span></code><br/><code><span leaf="">CMP W10, W9</span></code><br/><code><span leaf="">C. CS           loc_FFFFFFF008494928 ; <span class="code-snippet__attribute">va</span> &gt; elem_size1</span></code><br/></pre></p><p style="margin-left: 0cm;"><span lang="EN-US"><span style="background:yellow;mso-highlight:
yellow;"><span leaf="">    判断</span></span></span><span lang="EN-US"><span leaf="">va</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">是否跨</span></span><span lang="EN-US"><span leaf="">page</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="apache"><code><span leaf=""><span class="code-snippet__attribute">UBFX</span> X9, X1, #<span class="code-snippet__number">0</span>xE, #<span class="code-snippet__number">0</span>x20 ; &#39; &#39; ; index = (uint43_t)(va &gt;&gt; <span class="code-snippet__number">0</span>xe)</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">ADRP</span> X10, <a class="wx_topic_link" topic-id="mjxki4n6-i0m2zs" style="color: #576B95 !important;" data-topic="1">#qword</a>_FFFFFFF0077ED1D0@PAGE ;zone_info.zi_meta_base</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">LDR</span> X10,<span class="code-snippet__meta"> [X10,#qword_FFFFFFF0077ED1D0@PAGEOFF]</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">LSL</span> X9, X9, #<span class="code-snippet__number">4</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">LDRH</span> W9,<span class="code-snippet__meta"> [X10,X9]</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">AND</span> W9, W9, #<span class="code-snippet__number">0</span>x3FF ; zm_index = (zone_info.zi_meta_base[index &lt;&lt; <span class="code-snippet__number">4</span>] &amp; <span class="code-snippet__number">0</span>x3ff)</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">CMP</span> W9, W0</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">B</span>.NE            loc_FFFFFFF008494928 ; meta-&gt;zm_index != zid</span></code><br/></pre></p><p style="margin-left: 0cm;"><span lang="EN-US"><span style="background:yellow;mso-highlight:yellow;"><span leaf="">    判断</span></span></span><span lang="EN-US"><span leaf="">va</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">对应的</span></span><span lang="EN-US"><span leaf="">Meta</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">指向的</span></span><span lang="EN-US"><span leaf="">zm_index</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">是否与参数</span></span><span lang="EN-US"><span leaf="">zid</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">相等。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="nginx"><code><span leaf=""><span class="code-snippet__attribute">SUB</span> X9, X8, X2</span></code><br/><code><span leaf="">CMP X9, X3</span></code><br/><code><span leaf="">C. CC           loc_FFFFFFF0084948D0 ; <span class="code-snippet__attribute">elem_size</span> - offset &gt; new_data_size</span></code><br/><code><span leaf="">CMP X8, X2</span></code><br/><code><span leaf="">B.LS loc_FFFFFFF0084948FC ; <span class="code-snippet__attribute">elem_size</span> &lt; offset</span></code><br/><code><span leaf="">LDP X29, X30, [SP,<span class="code-snippet__comment">#0x30+var_s0]</span></span></code><br/><code><span leaf="">ADD SP, SP, <span class="code-snippet__comment">#0x40 ; &#39;@&#39;</span></span></code><br/><code><span leaf="">RETAB</span></code><br/></pre></p><p><span lang="EN-US"><span leaf=""><span textstyle="" style="font-weight: bold;">3</span></span></span><span style="mso-bookmark:
_Toc24355;"><span lang="EN-US" style="mso-fareast-language:ZH;"><span leaf=""><span textstyle="" style="font-weight: bold;">.3.2.2</span></span></span><span lang="EN-US"><span leaf=""><span textstyle="" style="font-weight: bold;"> zalloc_ro_mut_atomic</span></span></span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf="">__attribute__((noinline))</span></code><br/><code><span leaf=""><span class="code-snippet__function"><span class="code-snippet__type">uint64_t</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__title">zalloc_ro_mut_atomic</span><span class="code-snippet__params">(</span><span class="code-snippet__params"><span class="code-snippet__type">zone_id_t</span></span><span class="code-snippet__params"> zid, </span><span class="code-snippet__params"><span class="code-snippet__type">void</span></span><span class="code-snippet__params"> *elem, </span><span class="code-snippet__params"><span class="code-snippet__type">vm_offset_t</span></span><span class="code-snippet__params"> offset,</span></span></code><br/><code><span leaf=""><span class="code-snippet__type">zro_atomic_op_t</span> op, <span class="code-snippet__type">uint64_t</span> value)</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""> value = <span class="code-snippet__built_in">pmap_ro_zone_atomic_op</span>(zid, (<span class="code-snippet__type">vm_offset_t</span>)elem, offset, op, value);</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">return</span> value;</span></code><br/><code><span leaf="">}</span></code><br/></pre></p><h3><span style="mso-bookmark:_Toc13714;"><span style="mso-bookmark:_Toc23947;"><span lang="EN-US"><span leaf=""><span textstyle="" style="font-weight: bold;">3.3.2.3 zalloc_ro_clear</span></span></span></span></span></h3><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf=""><span class="code-snippet__function"><span class="code-snippet__type">void</span></span></span></code><br/><code><span leaf=""><span class="code-snippet__title">zalloc_ro_clear</span><span class="code-snippet__params">(</span><span class="code-snippet__params"><span class="code-snippet__type">zone_id_t</span></span><span class="code-snippet__params"> zid, </span><span class="code-snippet__params"><span class="code-snippet__type">void</span></span><span class="code-snippet__params"> *elem, </span><span class="code-snippet__params"><span class="code-snippet__type">vm_offset_t</span></span><span class="code-snippet__params"> offset, </span><span class="code-snippet__params"><span class="code-snippet__type">vm_size_t</span></span><span class="code-snippet__params"> size)</span></span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf=""> <span class="code-snippet__built_in">pmap_ro_zone_bzero</span>(zid, (<span class="code-snippet__type">vm_offset_t</span>)elem, offset, size);</span></code><br/><code><span leaf="">}</span></code><br/></pre></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="nginx"><code><span leaf=""><span class="code-snippet__attribute">pmap_ro_zone_bzero_ppl</span> ; <span class="code-snippet__attribute">DATA</span> XREF:</span></code><br/><code><span leaf="">BL pmap_ro_zone_validate_element ;</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOV</span> X0, X19</span></code><br/><code><span leaf="">MOV X1, X21</span></code><br/><code><span leaf="">MOV X2, X20</span></code><br/><code><span leaf="">BL pmap_ro_zone_lock_phy_page</span></code><br/><code><span leaf="">MOV X0, X19 ; <span class="code-snippet__attribute">vm_offset_t</span></span></code><br/><code><span leaf="">BL _ml_static_ptovirt_0</span></code><br/><code><span leaf="">MOV X1, X20 ; <span class="code-snippet__attribute">size_t</span></span></code><br/><code><span leaf="">BL _bzero</span></code><br/></pre></p><p><span lang="EN-US"><span style="background:yellow;mso-highlight:yellow;"><span leaf="">    逻辑与前面类似，只是调用了</span></span></span><span lang="EN-US"><span leaf="">bzero</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。</span></span></p><p style="display: none;"><mp-style-type data-value="3"></mp-style-type></p>


<p><a href="%27%27">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=1f1d38aa&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg4NjU1NDU4MA%3D%3D%26mid%3D2247483872%26idx%3D1%26sn%3D167c757186931b3f09d7993c9d5d8677">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Sat, 03 Jan 2026 08:34:00 +0800</pubDate>
    </item>
    <item>
      <title>IOS SPTM深度分析</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg4NjU1NDU4MA==&amp;mid=2247483864&amp;idx=1&amp;sn=399ce7d4205f1273e9834467678e5b6d</link>
      <description>本文深度分析了IOS SPTM代码实现细节</description>
      <content:encoded><![CDATA[<p>原创 <span>wzt</span> <span>2026-01-02 17:57</span> <span style="display: inline-block;">浙江</span></p>






  
  <p><img src="https://wechat2rss.xlab.app/img-proxy/?k=e6ca6059&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_jpg%2F4iaJia7Cvd3PCeibxXOIGLRw6XZ7fY9oXHBq1TNkAMdUy2yDqXK11BjPWFtxzBicU1rQHErbNMcXkI1AzvJm76Dnsw%2F0%3Fwx_fmt%3Djpeg"/></p>
  <p>本文深度分析了IOS SPTM代码实现细节</p>
  <h1 style="margin-left:0cm;text-indent:0cm;mso-list:l0 level1 lfo1;" data-pm-slice="0 0 []"><span lang="EN-US" style="mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;mso-bidi-font-family:Calibri;mso-bidi-theme-font:minor-latin;"><span style="mso-list:Ignore;"><span leaf=""><span textstyle="" style="font-size: 24px;font-weight: bold;">1 SPTM启动</span></span></span></span></h1><h1 data-pm-slice="0 0 []"><span lang="EN-US"><span leaf=""><span textstyle="" style="font-size: 24px;font-weight: bold;">2 GL Entry</span></span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf=""><span textstyle="" style="font-size: 24px;font-weight: bold;">分析</span></span></span></h1><h1 data-pm-slice="0 0 []"><span lang="EN-US"><span leaf=""><span textstyle="" style="font-size: 24px;font-weight: bold;">3 Exception</span></span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf=""><span textstyle="" style="font-size: 24px;font-weight: bold;">处理分析</span></span></span></h1><h1 data-pm-slice="0 0 []"><span lang="EN-US"><span leaf=""><span textstyle="" style="font-size: 24px;font-weight: bold;">4 Sptm</span></span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf=""><span textstyle="" style="font-size: 24px;font-weight: bold;">页表保护</span></span></span></h1><h1 data-pm-slice="0 0 []"><span lang="EN-US"><span leaf=""><span textstyle="" style="font-size: 24px;font-weight: bold;">5 Sptm retype</span></span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf=""><span textstyle="" style="font-size: 24px;font-weight: bold;">分类保护</span></span></span></h1><h1 data-pm-slice="0 0 []"><span lang="EN-US"><span leaf=""><span textstyle="" style="font-size: 24px;font-weight: bold;">6 TXM分析</span></span></span></h1><h1 style="margin-left:0cm;text-indent:0cm;mso-list:l0 level1 lfo1;" data-pm-slice="0 0 []"><span lang="EN-US" style="mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;mso-bidi-font-family:Calibri;mso-bidi-theme-font:minor-latin;"><span style="mso-list:Ignore;"><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">1. </span></span></span></span><span lang="EN-US"><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">sptm</span></span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">启动</span></span></span></h1><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="makefile"><code><span leaf="">MRS X0, <span class="code-snippet__comment">#0, c4, c2, #2 ; CurrentEL</span></span></code><br/><code><span leaf="">CMP X0, <span class="code-snippet__comment">#8</span></span></code><br/><code><span leaf="">B.NE loc_FFFFFFF00706B074 ; != EL2</span></code><br/><code><span leaf="">MRS X0, <span class="code-snippet__comment">#4, c1, c1, #0 ; HCR_EL2</span></span></code><br/><code><span leaf="">ORR X0, X0, <span class="code-snippet__comment">#0x8000000 ; TGE, bit [27] All exceptions that would be routed to EL1 are routed to EL2.</span></span></code><br/><code><span leaf="">ORR X0, X0, <span class="code-snippet__comment">#0x400000000 ; E2H, bit [34], The facilities to support a Host Operating System at EL2 are enabled.</span></span></code><br/><code><span leaf="">MSR <span class="code-snippet__comment">#4, c1, c1, #0, X0 ;</span></span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    首先判断如果在</span></span><span lang="EN-US"><span leaf="">el2</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">状态，则设置</span></span><span lang="EN-US"><span leaf="">hcr_el2</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">的</span></span><span lang="EN-US"><span leaf="">TGE</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">和</span></span><span lang="EN-US"><span leaf="">E2H</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">状态。</span></span><span lang="EN-US"><span leaf=""> sptm</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">由</span></span><span lang="EN-US"><span leaf="">iboot</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">加载，</span></span><span lang="EN-US"><span leaf="">iboot</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">跳转到</span></span><span lang="EN-US"><span leaf="">sptm</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">时处于</span></span><span lang="EN-US"><span leaf="">el2</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">状态。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="apache"><code><span leaf=""><span class="code-snippet__attribute">ADRL</span> X30, sptm_init_subsystem</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOV</span> X21, X20</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">ADRL</span> X0, unk_FFFFFFF0070B0000</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">ADD</span> X0, X0, X22</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">SUB</span> X0, X0, X23</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MSR</span> #<span class="code-snippet__number">5</span>, #<span class="code-snippet__number">0</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOV</span> SP, X0</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOV</span> X24, #<span class="code-snippet__number">1</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">B</span> init_hardware_registers ;</span></code><br/></pre></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">   执行</span></span><span lang="EN-US"><span leaf="">init_hardware_registers</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，后在跳转到</span></span><span lang="EN-US"><span leaf="">sptm_init_subsystem</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">继续执行。</span></span></p><p style=""><span lang="EN-US"><span leaf="">init_hardware_registers</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">的执行流程：</span></span></p><p><span lang="EN-US"><span leaf="">- </span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">设置</span></span><span lang="EN-US"><span leaf="">SPRR_PPERM_EL1</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">寄存器为</span></span><span lang="EN-US"><span leaf="">0x2020a52a302afaf5</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。</span></span></p><p><span lang="EN-US"><span leaf="">- </span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">设置</span></span><span lang="EN-US"><span leaf="">TCR_EL1</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">为</span></span><span lang="EN-US"><span leaf="">0x0800236511a511</span></span></p><p><span lang="EN-US"><span leaf="">- </span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">设置</span></span><span lang="EN-US"><span leaf="">TTBR0_EL1</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">为</span></span><span lang="EN-US"><span leaf="">0xFFFFFFF007010000</span></span></p><p><span lang="EN-US"><span leaf="">- </span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">设置</span></span><span lang="EN-US"><span leaf="">TTBR1_EL1</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">为</span></span><span lang="EN-US"><span leaf="">0xFFFFFFF0070A0000</span></span></p><p><span lang="EN-US"><span leaf="">- </span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">重新设置</span></span><span lang="EN-US"><span leaf="">APCTL_EL1</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。</span></span></p><p><span lang="EN-US"><span leaf="">- </span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">用</span></span><span lang="EN-US"><span leaf="">0xFEEDFACEFEEDFACF</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">依次设置</span></span><span lang="EN-US"><span leaf="">APIBKey_EL1</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">APDBKey_EL1</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">KERNKE_EL1</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">（苹果新增）、</span></span><span lang="EN-US"><span leaf=""> APIAKey_EL1</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">APDAKey_EL1</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">APGAKey_EL1</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。</span></span></p><p><span lang="EN-US"><span leaf="">- </span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">设置</span></span><span lang="EN-US"><span leaf="">SCTLR_EL1</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">为</span></span><span lang="EN-US"><span leaf="">0x01000fc14713d</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。</span></span></p><p><span lang="EN-US"><span leaf="">- </span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">设置若干</span></span><span lang="EN-US"><span leaf="">HID*</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">寄存器（苹果新增）。</span></span></p><p style=""><span lang="EN-US"><span leaf="">sptm_init_subsystem</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">的执行流程：</span></span></p><p><span lang="EN-US"><span leaf="">- </span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">调用</span></span><span lang="EN-US"><span leaf="">copy_and_clear_random_seed</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">生成若干随机种子。</span></span></p><p><span lang="EN-US"><span leaf="">- </span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">调用</span></span><span lang="EN-US"><span leaf="">init_xnu_ro_data</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">初始化</span></span><span lang="EN-US"><span leaf="">xnu_ro_pagetables_begin</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">xnu_ro_pagetables_end</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span></p><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">xnu_exc_return_handler</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">xnu_ctrr_dispatch_table</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">等全局变量。</span></span></p><p style="tab-stops:285.7pt;"><span lang="EN-US"><span leaf="">- </span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">调用</span></span><span lang="EN-US"><span leaf="">validate_region_order</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">检查</span></span><span lang="EN-US"><span leaf="">txm</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">的地址范围。</span></span></p><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">- </span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">调用</span></span><span lang="EN-US"><span leaf="">register_papt_range</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">依次注册</span></span><span lang="EN-US"><span leaf="">SPTM-rx</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">SPTM-rw</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">SPTM-le</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">TXM-ro</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">TXM-rx</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">TXM-bx</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">TXM-rw</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">BootKC-ro</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">BootKC-rs</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">BootKC-rx</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">BootKC-bx</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">BootKC-rw</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">BootKC-le</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">TrustCache</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">CL4-ro</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">CL4-rx</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">CL4-rw</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">CL4-le</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">RAMDisk</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">RTBuddySeg</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">SEPFW</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">SEPPatches</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">uStuff</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">preoslog</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">BootArgs</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">ExclaveOSIntegrityCatalog</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">ExclaveOSTrustCache</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">AVAILABLE</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">PHYS_SLIDE</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">等地址范围信息。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf=""><span class="code-snippet__built_in">register_papt_range</span>(<span class="code-snippet__type">char</span> *name, <span class="code-snippet__type">uint64_t</span> type, <span class="code-snippet__type">uint64_t</span> flag)</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf="">   <span class="code-snippet__built_in">init_get_image_region</span>(name)；</span></code><br/><code><span leaf="">   <span class="code-snippet__built_in">bootstrap_register_papt_range</span>();</span></code><br/><code><span leaf="">}</span></code><br/></pre></p><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">bootstrap_register_papt_range</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">向</span></span><span lang="EN-US"><span leaf="">papt_range_array</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">数组注册一个地址范围信息：</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf=""><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">papt_range_array</span> {</span></code><br/><code><span leaf="">   <span class="code-snippet__type">char</span> *name;</span></code><br/><code><span leaf=""><span class="code-snippet__number">+0x8</span>:</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> type;</span></code><br/><code><span leaf=""><span class="code-snippet__number">+0x10</span>:</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> start_address;</span></code><br/><code><span leaf=""><span class="code-snippet__number">+0x18</span>:</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> base;</span></code><br/><code><span leaf=""><span class="code-snippet__number">+0x20</span>:</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> end_address;</span></code><br/><code><span leaf=""><span class="code-snippet__number">+0x24</span>:</span></code><br/><code><span leaf="">   <span class="code-snippet__type">char</span> flag;</span></code><br/><code><span leaf=""><span class="code-snippet__number">+0x28</span>:</span></code><br/><code><span leaf="">};</span></code><br/></pre></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf=""><span class="code-snippet__built_in">bootstrap_register_papt_range</span>(<span class="code-snippet__type">char</span> *name, <span class="code-snippet__type">uint64_t</span> type, <span class="code-snippet__type">uint64_t</span> start_addr, <span class="code-snippet__type">uint64_t</span> end_addr, <span class="code-snippet__type">uint64_t</span> flag)</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf="">  papt_range_array[papt_range_array_length].name = name;</span></code><br/><code><span leaf="">  papt_range_array[papt_range_array_length].type = type;</span></code><br/><code><span leaf="">  papt_range_array[papt_range_array_length].start_address = start_addr;</span></code><br/><code><span leaf="">  papt_range_array[papt_range_array_length]end_address = end_addr;</span></code><br/><code><span leaf="">  papt_range_array[papt_range_array_length].flag = flag;</span></code><br/><code><span leaf="">  papt_range_array_length++</span></code><br/></pre></p><table style="border-collapse:collapse;border:none;mso-border-alt:solid windowtext .5pt;mso-yfti-tbllook:1184;mso-padding-alt:0cm 5.4pt 0cm 5.4pt;"></table><table style="border-collapse:collapse;border:none;mso-border-alt:solid windowtext .5pt;mso-yfti-tbllook:1184;mso-padding-alt:0cm 5.4pt 0cm 5.4pt;"></table><table style="border-collapse:collapse;border:none;mso-border-alt:solid windowtext .5pt;mso-yfti-tbllook:1184;mso-padding-alt:0cm 5.4pt 0cm 5.4pt;"><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table style="border-collapse:collapse;border:none;mso-border-alt:solid windowtext .5pt;mso-yfti-tbllook:1184;mso-padding-alt:0cm 5.4pt 0cm 5.4pt;"><caption></caption><tfoot><tr><td><p><span leaf=""><br/></span></p></td></tr></tfoot></table><table></table><table><caption></caption><tfoot><tr><td><p><span leaf=""><br/></span></p></td></tr></tfoot></table><table></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td><p><span leaf=""><br/></span></p></td></tr></tfoot></table><table></table><p><span leaf=""><br/></span></p><table></table><table></table><table style="width:25px;"><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table style="width:25px;"><caption></caption><tfoot><tr><td></td></tr></tfoot></table><p><span leaf=""><br/></span></p><table></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col style="width: 189px;"/><col style="width: 189px;"/><col style="width: 189px;"/></colgroup><tbody><tr style="mso-yfti-irow:0;mso-yfti-firstrow:yes;"><td data-colwidth="189" width="189" valign="top" style="border: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">Name</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: 1pt solid windowtext;border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-image: initial;border-left: none;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">Type</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: 1pt solid windowtext;border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-image: initial;border-left: none;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">Flag</span></span></p></td></tr><tr style="mso-yfti-irow:1;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">DeviceTree</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0xb</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x20</span></span></p></td></tr><tr style="mso-yfti-irow:2;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">SPTM-ro</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x2</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x28</span></span></p></td></tr><tr style="mso-yfti-irow:3;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">SPTM-rx</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x4</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x21</span></span></p></td></tr><tr style="mso-yfti-irow:4;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">SPTM-rw</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x2</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x21</span></span></p></td></tr><tr style="mso-yfti-irow:5;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">SPTM-le</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x2</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x21</span></span></p></td></tr><tr style="mso-yfti-irow:6;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">TXM-ro</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x20</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x48</span></span></p></td></tr><tr style="mso-yfti-irow:7;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">TXM-rx</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x20</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x41</span></span></p></td></tr><tr style="mso-yfti-irow:8;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">TXM-bx</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x5</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x41</span></span></p></td></tr><tr style="mso-yfti-irow:9;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">TXM-rw</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x20</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x41</span></span></p></td></tr><tr style="mso-yfti-irow:10;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">TXM-le</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x20</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x41</span></span></p></td></tr><tr style="mso-yfti-irow:11;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">BootKC-ro</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0xb</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x48</span></span></p></td></tr><tr style="mso-yfti-irow:12;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">BootKC-rs</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0xb</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x41</span></span></p></td></tr><tr style="mso-yfti-irow:13;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">BootKC-rx</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0xb</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x41</span></span></p></td></tr><tr style="mso-yfti-irow:14;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">BootKC-bx</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">x</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x41</span></span></p></td></tr><tr style="mso-yfti-irow:15;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">BootKC-rw</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0xb</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x51</span></span></p></td></tr><tr style="mso-yfti-irow:16;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">BootKC-le</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0xb</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x51</span></span></p></td></tr><tr style="mso-yfti-irow:17;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">TrustCache</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x0</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x40</span></span></p></td></tr><tr style="mso-yfti-irow:18;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">CL4-ro</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x32</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x6</span></span></p></td></tr><tr style="mso-yfti-irow:19;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">CL4-rx</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x32</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x6</span></span></p></td></tr><tr style="mso-yfti-irow:20;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">CL4-rw</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x32</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x6</span></span></p></td></tr><tr style="mso-yfti-irow:21;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">CL4-le</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x32</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x6</span></span></p></td></tr><tr style="mso-yfti-irow:22;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">RAMDisk</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0xb</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x2</span></span></p></td></tr><tr style="mso-yfti-irow:23;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">RTBuddySeg</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0xb</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x2</span></span></p></td></tr><tr style="mso-yfti-irow:24;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">SEPFW</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0xb</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x2</span></span></p></td></tr><tr style="mso-yfti-irow:25;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">SEPPatches</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0xb</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x2</span></span></p></td></tr><tr style="mso-yfti-irow:26;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">uStuff</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0xb</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x2</span></span></p></td></tr><tr style="mso-yfti-irow:27;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">Preoslog</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0xb</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x2</span></span></p></td></tr><tr style="mso-yfti-irow:28;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">BootArgs</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0xb</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x0</span></span></p></td></tr><tr style="mso-yfti-irow:29;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">ExclaveOSIntegrityCatalog</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x32</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x6</span></span></p></td></tr><tr style="mso-yfti-irow:30;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">ExclaveOSTrustCache</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">0x32</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x6</span></span></p></td></tr><tr style="mso-yfti-irow:31;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">AVAILABLE</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">0x0</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x0</span></span></p></td></tr><tr style="mso-yfti-irow:32;mso-yfti-lastrow:yes;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">PHYS_SLIDE</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">0xb</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:341.6pt;"><span lang="EN-US"><span leaf="">0x0</span></span></p></td></tr></tbody></table><p><span lang="EN-US"><span leaf="">- </span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">调用</span></span><span lang="EN-US"><span leaf="">sptm_bootstrap_early</span></span></p><p><span lang="EN-US"><span leaf="">- </span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">调用初始化</span></span><span lang="EN-US"><span leaf="">sprr</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">相关寄存器：</span></span></p><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">设置</span></span><span lang="EN-US"><span leaf="">SPRR_PPERM_EL1 - sprr kernel permission</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">寄存器值为</span></span><span lang="EN-US"><span leaf="">0x2020a52a302afaf5</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">。</span></span></p><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">设置</span></span><span lang="EN-US"><span leaf="">SPRR_UPERM_EL0 - sprr user permission</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">寄存器值为</span></span><span lang="EN-US"><span leaf="">0x2010002030100000</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">。</span></span></p><p><span lang="EN-US"><span leaf="">- </span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">调用</span></span><span lang="EN-US"><span leaf="">init_gxf_mode_prev</span></span></p><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">设置</span></span><span lang="EN-US"><span leaf="">GXF_CONFIG_EL1</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">寄存器为</span></span><span lang="EN-US"><span leaf="">1</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。</span></span></p><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">设置</span></span><span lang="EN-US"><span leaf="">GXF_PABENTRY_EL1</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">。</span></span></p><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">设置</span></span><span lang="EN-US"><span leaf="">GXF_ENTRY_EL1</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">为</span></span><span lang="EN-US"><span leaf="">sub_FFFFFFF00706C808</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">。</span></span></p><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">执行</span></span><span lang="EN-US"><span leaf="">0x201420</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">指令进入</span></span><span lang="EN-US"><span leaf="">Guard Level</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">模式，</span></span><span lang="EN-US"><span leaf=""> GL</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">的入口地址设置为</span></span><span lang="EN-US"><span leaf="">sub_FFFFFFF00706C808</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="apache"><code><span leaf=""><span class="code-snippet__attribute">__text</span>:FFFFFFF00706C808 sub_FFFFFFF00706C808 ; DATA XREF:</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MSR</span> #<span class="code-snippet__number">6</span>, c15, c11, #<span class="code-snippet__number">1</span>, X0 ; TPIDR_GL2 - Software Thread ID Register (GL2)</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOVK</span> X0, #<span class="code-snippet__number">0</span>x2020,LSL#<span class="code-snippet__number">48</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOVK</span> X0, #<span class="code-snippet__number">0</span>xA52A,LSL#<span class="code-snippet__number">32</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOVK</span> X0, #<span class="code-snippet__number">0</span>x302A,LSL#<span class="code-snippet__number">16</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOVK</span> X0, #<span class="code-snippet__number">0</span>xFAE6 ; <span class="code-snippet__number">0</span>x2020a52a302afae6</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MSR</span> #<span class="code-snippet__number">6</span>, c15, c1, #<span class="code-snippet__number">6</span>, X0 ; SPRR_PPERM_EL1 - SPRR Kernel Permission Configuration Register (EL1)</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOVK</span> X0, #<span class="code-snippet__number">0</span>,LSL#<span class="code-snippet__number">48</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOVK</span> X0, #<span class="code-snippet__number">0</span>,LSL#<span class="code-snippet__number">32</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOVK</span> X0, #<span class="code-snippet__number">0</span>,LSL#<span class="code-snippet__number">16</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOVK</span> X0, #<span class="code-snippet__number">0</span>xFF</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MSR</span> #<span class="code-snippet__number">6</span>, c15, c1, #<span class="code-snippet__number">0</span>, X0 ; SPRR_CONFIG_EL1 - SPRR Configuration Register (EL1)</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">RET</span></span></code><br/></pre></p><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">首先设置</span></span><span lang="EN-US"><span leaf="">TPIDR_GL2</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">寄存器为</span></span><span lang="EN-US"><span leaf="">init_gl2_thread</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf="">gl2_thread {</span></code><br/><code><span leaf=""><span class="code-snippet__number">+0x0</span>:</span></code><br/><code><span leaf="">   <span class="code-snippet__type">char</span> domain_type;</span></code><br/><code><span leaf=""><span class="code-snippet__number">+0x8</span>:</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> tls_index;</span></code><br/><code><span leaf=""><span class="code-snippet__number">+0x18</span>:</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> gl2_sp;</span></code><br/><code><span leaf=""><span class="code-snippet__number">+0x20</span>:</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> unknown;</span></code><br/><code><span leaf=""><span class="code-snippet__number">+0x28</span>:</span></code><br/><code><span leaf="">   <span class="code-snippet__type">char</span> sptm_state;</span></code><br/><code><span leaf=""><span class="code-snippet__number">+0x30</span>:</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> hop_flag;</span></code><br/><code><span leaf=""><span class="code-snippet__number">+0x38</span>:</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">save_caller_reg</span> {</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> x0,x1,x2,x3,x4,x5,x6,x7;</span></code><br/><code><span leaf="">};</span></code><br/><code><span leaf=""><span class="code-snippet__number">+0x78</span>:</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">save_exception_reg</span> {</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> <span class="code-snippet__number">0x0</span>;</span></code><br/><code><span leaf="">   ...</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> <span class="code-snippet__number">0xb0</span>;</span></code><br/><code><span leaf=""> };</span></code><br/><code><span leaf=""><span class="code-snippet__number">+0xf8</span>:</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> gl1_sp;</span></code><br/><code><span leaf=""><span class="code-snippet__number">+0x130</span>:</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">save_exception_reg</span> {</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> <span class="code-snippet__number">0x0</span>;</span></code><br/><code><span leaf="">   ...</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> <span class="code-snippet__number">0xb0</span>;</span></code><br/><code><span leaf=""> };</span></code><br/><code><span leaf=""><span class="code-snippet__number">+0x1f0</span>:</span></code><br/><code><span leaf=""> <span class="code-snippet__type">uint64_t</span> gl0_sp;</span></code><br/><code><span leaf=""><span class="code-snippet__number">+0x520</span>:</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">union</span> {</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">config_reg</span> {</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> save_caller_arg_address;</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> sprr_user_permission;</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> id_isar2_el1;</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> unknown;</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> apctl_el1;</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> sctlr_el1;</span></code><br/><code><span leaf=""> };</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">config_reg1</span> {</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> tpidr_el0;</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> tpidrro_el0;</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> sprr_pperm_el12;</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> sprr_uperm_el02</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> gxf_config_el12;</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> sprr_config_el12;</span></code><br/><code><span leaf="">   ...</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> tpidr_gl1;</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> unknown;</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> vbar_gl12;</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> unknown;</span></code><br/><code><span leaf=""><span class="code-snippet__number">+0x88</span>:</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> hcr_el2;</span></code><br/><code><span leaf=""> };</span></code><br/><code><span leaf=""><span class="code-snippet__number">+0x5b0</span>:</span></code><br/><code><span leaf=""> strucct config_reg2 {</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span>;</span></code><br/><code><span leaf=""> <span class="code-snippet__number">+0x88</span>:</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span>;</span></code><br/><code><span leaf=""> };</span></code><br/><code><span leaf=""><span class="code-snippet__number">+0x640</span>:</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">unknown_reg_store</span> {</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> x0,x1,x2,x3,x4,x5,x6,x7;</span></code><br/><code><span leaf=""> };</span></code><br/><code><span leaf=""><span class="code-snippet__number">+0x668</span>:</span></code><br/><code><span leaf=""> <span class="code-snippet__type">char</span> el_level;</span></code><br/><code><span leaf=""><span class="code-snippet__number">+0x680</span>:</span></code><br/><code><span leaf=""> <span class="code-snippet__type">uint64_t</span> current_cpu;</span></code><br/><code><span leaf=""><span class="code-snippet__number">+0x7f0</span>:</span></code><br/><code><span leaf=""> <span class="code-snippet__type">uint64_t</span> value;</span></code><br/><code><span leaf=""><span class="code-snippet__number">+0x7f8</span>:</span></code><br/><code><span leaf=""> <span class="code-snippet__type">uint64_t</span> unknown;</span></code><br/><code><span leaf=""><span class="code-snippet__number">+0x870</span>:</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">unknown_ctrr_struct</span> *ctrr;</span></code><br/><code><span leaf="">};</span></code><br/><code><span leaf=""><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">unknown_ctrr_struct</span> {</span></code><br/><code><span leaf=""> <span class="code-snippet__type">uint64_t</span> value1;</span></code><br/><code><span leaf=""><span class="code-snippet__number">+0x800</span>:</span></code><br/><code><span leaf=""> <span class="code-snippet__type">uint64_t</span> value2;</span></code><br/><code><span leaf="">};</span></code><br/></pre></p><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">    重新设置</span></span><span lang="EN-US"><span leaf="">SPRR_PPERM_EL1 - sprr kernel permission</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">寄存器值为</span></span><span lang="EN-US"><span leaf="">0x2020a52a302afae6</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。</span></span></p><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">    重新设置</span></span><span lang="EN-US"><span leaf="">SPRR_CONFIG_EL1</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">为</span></span><span lang="EN-US"><span leaf="">0xff</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。</span></span></p><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">注意随后使用的是</span></span><span lang="EN-US"><span leaf="">ret</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">指令，</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">而不是</span></span><span lang="EN-US"><span leaf="">0x201400</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">，说明并没有推出</span></span><span lang="EN-US"><span leaf="">GL</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">模式，从而让</span></span><span lang="EN-US"><span leaf="">sptm</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">从普通的</span></span><span lang="EN-US"><span leaf="">el2</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">模式进入到</span></span><span lang="EN-US"><span leaf="">GL2</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">模式继续运行。</span></span></p><p><span lang="EN-US"><span leaf="">- </span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">调用</span></span><span lang="EN-US"><span leaf="">init_sptm_mode</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">继续初始化</span></span><span lang="EN-US"><span leaf="">sptm</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。</span></span></p><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">锁定</span></span><span lang="EN-US"><span leaf="">VMSA_LOCK_EL1</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">寄存器。</span></span></p><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">用</span></span><span lang="EN-US"><span leaf="">CTRR_A_UPR/LOW_EL1</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">寄存器锁定</span></span><span lang="EN-US"><span leaf="">el1</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">地址范围。</span></span></p><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">用</span></span><span lang="EN-US"><span leaf="">CTRR_A_UPR/LOW_EL2</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">寄存器锁定</span></span><span lang="EN-US"><span leaf="">el2</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">地址范围。</span></span></p><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">调用</span></span><span lang="EN-US"><span leaf="">init_gxf_mode_final</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">，它将</span></span><span lang="EN-US"><span leaf="">GXF_ENTRY_EL1</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">设置为</span></span><span lang="EN-US"><span leaf="">gxf_entry_el1</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">函数地址，将</span></span><span lang="EN-US"><span leaf="">VBAR_GL1</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">设置为</span></span><span lang="EN-US"><span leaf="">syn_handler_sp0_g12</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">地址，将</span></span><span lang="EN-US"><span leaf="">GXF_CONFIG_EL1</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">重新设置为</span></span><span lang="EN-US"><span leaf="">0x2d</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。</span></span></p><p><span lang="EN-US"><span leaf="">- </span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">分别设置</span></span><span lang="EN-US"><span leaf="">elr_gl1_cl4</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">elr_gl1_txm</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">elr_gl1_kernelcache</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">三个全局变量。</span></span></p><p><span lang="EN-US"><span leaf="">- </span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">调用</span></span><span lang="EN-US"><span leaf="">sptm_register_dispatch_table</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">注册当前</span></span><span lang="EN-US"><span leaf="">domain</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">的三个</span></span><span lang="EN-US"><span leaf="">dispatch_table</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">函数。</span></span></p><table style="border-collapse:collapse;border:none;mso-border-alt:solid windowtext .5pt;mso-yfti-tbllook:1184;mso-padding-alt:0cm 5.4pt 0cm 5.4pt;"></table><p><span leaf=""><br/></span></p><table></table><p><span leaf=""><br/></span></p><table></table><p><span leaf=""><br/></span></p><table></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col style="width: 189px;"/><col style="width: 189px;"/><col style="width: 189px;"/></colgroup><tbody><tr style="mso-yfti-irow:0;mso-yfti-firstrow:yes;"><td data-colwidth="189" width="189" valign="top" style="border: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">table_id</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: 1pt solid windowtext;border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-image: initial;border-left: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">Dispatch function</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: 1pt solid windowtext;border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-image: initial;border-left: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">Table_permissions</span></span></p></td></tr><tr style="mso-yfti-irow:1;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">0</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">sptm_dispatch</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">2</span></span></p></td></tr><tr style="mso-yfti-irow:2;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">1</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:34.25pt;"><span lang="EN-US"><span leaf="">sptm_dispatch</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">4</span></span></p></td></tr><tr style="mso-yfti-irow:3;mso-yfti-lastrow:yes;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">2</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="tab-stops:34.25pt;"><span lang="EN-US"><span leaf="">sptm_dispatch</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">8</span></span></p></td></tr></tbody></table><p style="tab-stops:169.45pt;"><span lang="EN-US"><span leaf="">sptm_register_dispatch_table(uint64_t table_id, uint64_t dispatch_entry_point, uint64_t table_permissions)</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">当</span></span><span lang="EN-US"><span leaf="">gl2_thread-&gt;domain_type &lt; 2</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">时选择</span></span><span lang="EN-US"><span leaf="">xnu_ctrr_dispatch_table</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，否则选择</span></span><span lang="EN-US"><span leaf="">domain_id_array</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf="">domain_id_struct {</span></code><br/><code><span leaf=""> table_id_struct {</span></code><br/><code><span leaf=""> <span class="code-snippet__type">uint64_t</span> entry_point;</span></code><br/><code><span leaf=""> <span class="code-snippet__type">uint64_t</span> table_permissions;</span></code><br/><code><span leaf=""> <span class="code-snippet__type">uint64_t</span> value2;</span></code><br/><code><span leaf=""> }[<span class="code-snippet__number">16</span>];</span></code><br/><code><span leaf="">}[<span class="code-snippet__number">16</span>];</span></code><br/></pre></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="shell"><code><span leaf=""><span class="code-snippet__meta">domain_id_array[gl2_thread-&gt;</span>domain_type][table_id].entry_point = dispatch_entry_point;</span></code><br/><code><span leaf=""><span class="code-snippet__meta">domain_id_array[gl2_thread-&gt;</span>domain_type][table_id].table_permissions = table_permissions;</span></code><br/></pre></p><p style="mso-pagination:widow-orphan;"><span lang="EN-US" style="font-size:10.5pt;mso-bidi-font-size:12.0pt;mso-bidi-font-family:&#34;Times New Roman&#34;;mso-bidi-theme-font:
minor-bidi;mso-font-kerning:1.0pt;"><span leaf="">- </span></span><span style="font-size:10.5pt;mso-bidi-font-size:12.0pt;font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-bidi-font-family:
&#34;Times New Roman&#34;;mso-bidi-theme-font:minor-bidi;mso-font-kerning:1.0pt;"><span leaf="">至此</span></span><span lang="EN-US" style="font-size:10.5pt;mso-bidi-font-size:12.0pt;mso-bidi-font-family:
&#34;Times New Roman&#34;;mso-bidi-theme-font:minor-bidi;mso-font-kerning:1.0pt;"><span leaf="">sptm</span></span><span style="font-size:10.5pt;mso-bidi-font-size:12.0pt;font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-bidi-font-family:
&#34;Times New Roman&#34;;mso-bidi-theme-font:minor-bidi;mso-font-kerning:1.0pt;"><span leaf="">初始化完毕。</span></span></p><h1><span lang="EN-US"><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">2 GL Entry</span></span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">分析</span></span></span></h1><h2><span lang="EN-US"><span leaf="">2.1 gxf_entry_el1</span></span><span style="font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;"><span leaf="">分析</span></span></h2><p style=""><span lang="EN-US"><span leaf="">Kernelcache</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">和</span></span><span lang="EN-US"><span leaf="">sptm</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">启动阶段的代码会调用</span></span><span lang="EN-US"><span leaf="">0x201420</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">指令进入</span></span><span lang="EN-US"><span leaf="">Guard Level</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">模式，在</span></span><span lang="EN-US"><span leaf="">sptm</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">的启动阶段将</span></span><span lang="EN-US"><span leaf="">gxf_entry_el1</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">写入</span></span><span lang="EN-US"><span leaf="">GXF_ENTRY_EL1</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">寄存器，通过</span></span><span lang="EN-US"><span leaf="">x16</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">对其传递参数。</span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">除了</span></span><span lang="EN-US"><span leaf="">0x201420</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">指令，在</span></span><span lang="EN-US"><span leaf="">kernelcache</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">代码中，还看到了其他三种指令也能进入</span></span><span lang="EN-US"><span leaf="">GL</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">模式：</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="apache"><code><span leaf=""><span class="code-snippet__attribute">com</span>.apple.kernel:__text:FFFFFFF0284F63F0 sptm_txm_call ; CODE XREF: com.apple.kernel:__text:FFFFFFF028266D8C↑p</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">PACIBSP</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOV</span> W16, W0</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOVK</span> X16, #<span class="code-snippet__number">2</span>,LSL#<span class="code-snippet__number">48</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOVK</span> X16, #<span class="code-snippet__number">0</span>,LSL#<span class="code-snippet__number">32</span> ; <span class="code-snippet__number">0</span>x20000w0000000</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">MOV</span> X10, X1</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">LDP</span> X0, X1,<span class="code-snippet__meta"> [X10]</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">LDP</span> <a class="wx_topic_link" topic-id="mjwp4s6o-l9slsf" style="color: #576B95 !important;" data-topic="1">X2, X</a>3,<span class="code-snippet__meta"> [X10,#0x10]</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">LDP</span> <a class="wx_topic_link" topic-id="mjwp4s6p-znirdb" style="color: #576B95 !important;" data-topic="1">X4, X</a>5,<span class="code-snippet__meta"> [X10,#0x20]</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">LDP</span> X6, X7,<span class="code-snippet__meta"> [X10,#0x30]</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">DCD</span> <span class="code-snippet__number">0</span>x201420</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">RETAB</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">DCD</span> <span class="code-snippet__number">0</span>x201421</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">DCD</span> <span class="code-snippet__number">0</span>x201422</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">DCD</span> <span class="code-snippet__number">0</span>x201423</span></code><br/></pre></p><p><span lang="EN-US" style="background:yellow;mso-highlight:
yellow;"><span leaf="">在对</span></span><span lang="EN-US"><span leaf="">gxf_entry_el1</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">代码的追踪中，发现只有</span></span><span lang="EN-US"><span leaf="">0x201420</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">可以向</span></span><span lang="EN-US"><span leaf="">sptm</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">传递参数，其他三个只能调用特定的几个</span></span><span lang="EN-US"><span leaf="">dispatch</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">函数。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf=""><span class="code-snippet__built_in">gxf_entry_el1</span>(<span class="code-snippet__type">uint64_t</span> event_metadata)</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> esr_gl1 = <span class="code-snippet__built_in">msr</span>(ESR_GL1) &amp; <span class="code-snippet__number">0x1f</span>;        <span class="code-snippet__comment">// genter arg</span></span></code><br/><code><span leaf="">   <span class="code-snippet__keyword">if</span> (!(word_FFFFFFF007094018 &amp; <span class="code-snippet__number">0xf</span>)) {</span></code><br/><code><span leaf="">     <span class="code-snippet__keyword">if</span> (word_FFFFFFF007094018 != gl2_thread-&gt;<span class="code-snippet__number">0x680</span>) {</span></code><br/><code><span leaf="">       <span class="code-snippet__built_in">dispatch_state_machine</span>(<span class="code-snippet__number">0xb</span>, <span class="code-snippet__number">0</span>);    </span></code><br/><code><span leaf="">     }</span></code><br/><code><span leaf="">     <span class="code-snippet__keyword">else</span> {</span></code><br/><code><span leaf="">       <span class="code-snippet__keyword">if</span> (esr_gl1 == <span class="code-snippet__number">0</span>) {</span></code><br/><code><span leaf="">         <span class="code-snippet__keyword">if</span> (gl2_thread-&gt;unkown_flag != <span class="code-snippet__number">0</span>)</span></code><br/><code><span leaf="">           <span class="code-snippet__built_in">dead_loop</span>();</span></code><br/><code></code><br/><code><span leaf="">         <span class="code-snippet__type">uint64_t</span> domain_id = (metadata &gt;&gt; <span class="code-snippet__number">48</span>) &amp; <span class="code-snippet__number">0xffff</span>;</span></code><br/><code><span leaf="">         <span class="code-snippet__keyword">if</span> (domain_id == <span class="code-snippet__number">0</span>)</span></code><br/><code><span leaf="">           <span class="code-snippet__built_in">dispatch_state_machine</span>(<span class="code-snippet__number">2</span>, event_metadata);</span></code><br/><code><span leaf="">         <span class="code-snippet__keyword">else</span> <span class="code-snippet__keyword">if</span> (domain_id == <span class="code-snippet__number">3</span>)</span></code><br/><code><span leaf="">           <span class="code-snippet__built_in">dispatch_state_machine</span>(<span class="code-snippet__number">4</span>, event_metadata);</span></code><br/><code><span leaf="">         <span class="code-snippet__keyword">else</span> <span class="code-snippet__keyword">if</span> (domain_id == <span class="code-snippet__number">2</span>)</span></code><br/><code><span leaf="">           <span class="code-snippet__built_in">dispatch_state_machine</span>(<span class="code-snippet__number">3</span>, event_metadata);</span></code><br/><code><span leaf="">         <span class="code-snippet__keyword">else</span></span></code><br/><code><span leaf="">         <span class="code-snippet__built_in">genter_dispatch_entry_error</span>();</span></code><br/><code><span leaf="">     }</span></code><br/><code><span leaf="">     <span class="code-snippet__keyword">else</span> <span class="code-snippet__keyword">if</span> (esr_gl1 == <span class="code-snippet__number">1</span>) {</span></code><br/><code><span leaf="">       <span class="code-snippet__keyword">if</span> (gl2_thread-&gt;unkown_flag != <span class="code-snippet__number">0</span>)</span></code><br/><code><span leaf="">       <span class="code-snippet__built_in">dead_loop</span>();</span></code><br/><code><span leaf="">       <span class="code-snippet__built_in">dispatch_state_machine</span>(<span class="code-snippet__number">0xa</span>, <span class="code-snippet__number">0</span>);</span></code><br/><code><span leaf="">     }</span></code><br/><code><span leaf="">     <span class="code-snippet__keyword">else</span> {</span></code><br/><code><span leaf="">       <span class="code-snippet__built_in">genter_panic</span>();</span></code><br/><code><span leaf="">     }</span></code><br/><code><span leaf="">   }</span></code><br/><code><span leaf=""> }</span></code><br/><code><span leaf=""> <span class="code-snippet__keyword">else</span> {</span></code><br/><code><span leaf="">   <span class="code-snippet__keyword">if</span> (esr_gl1 == <span class="code-snippet__number">0</span>) {</span></code><br/><code><span leaf="">     <span class="code-snippet__keyword">if</span> (gl2_thread-&gt;unkown_flag != <span class="code-snippet__number">0</span>)</span></code><br/><code><span leaf="">       <span class="code-snippet__built_in">dead_loop</span>();</span></code><br/><code></code><br/><code><span leaf="">       <span class="code-snippet__type">uint64_t</span> domain_id = (metadata &gt;&gt; <span class="code-snippet__number">48</span>) &amp; <span class="code-snippet__number">0xffff</span>;</span></code><br/><code><span leaf="">       <span class="code-snippet__keyword">if</span> (domain_id == <span class="code-snippet__number">0</span>)</span></code><br/><code><span leaf="">         <span class="code-snippet__built_in">dispatch_state_machine</span>(<span class="code-snippet__number">2</span>, event_metadata);</span></code><br/><code><span leaf="">       <span class="code-snippet__keyword">else</span> <span class="code-snippet__keyword">if</span> (domain_id == <span class="code-snippet__number">3</span>)</span></code><br/><code><span leaf="">         <span class="code-snippet__built_in">dispatch_state_machine</span>(<span class="code-snippet__number">4</span>, event_metadata);</span></code><br/><code><span leaf="">        <span class="code-snippet__keyword">else</span> <span class="code-snippet__keyword">if</span> (domain_id == <span class="code-snippet__number">2</span>)</span></code><br/><code><span leaf="">         <span class="code-snippet__built_in">dispatch_state_machine</span>(<span class="code-snippet__number">3</span>, event_metadata);</span></code><br/><code><span leaf="">       <span class="code-snippet__keyword">else</span></span></code><br/><code><span leaf="">         <span class="code-snippet__built_in">genter_dispatch_entry_error</span>();</span></code><br/><code><span leaf="">       }</span></code><br/><code><span leaf="">     <span class="code-snippet__keyword">else</span> <span class="code-snippet__keyword">if</span> (esr_gl1 == <span class="code-snippet__number">1</span>) {</span></code><br/><code><span leaf="">       <span class="code-snippet__keyword">if</span> (gl2_thread-&gt;unkown_flag != <span class="code-snippet__number">0</span>)</span></code><br/><code><span leaf="">         <span class="code-snippet__built_in">dead_loop</span>();</span></code><br/><code><span leaf="">         <span class="code-snippet__built_in">dispatch_state_machine</span>(<span class="code-snippet__number">8</span>, <span class="code-snippet__number">0</span>);</span></code><br/><code><span leaf="">     }</span></code><br/><code><span leaf="">     <span class="code-snippet__keyword">else</span> <span class="code-snippet__keyword">if</span> (esr_gl1 == <span class="code-snippet__number">2</span>) {</span></code><br/><code><span leaf="">       <span class="code-snippet__keyword">if</span> (gl2_thread-&gt;unkown_flag != <span class="code-snippet__number">0</span>)</span></code><br/><code><span leaf="">         <span class="code-snippet__built_in">dead_loop</span>();</span></code><br/><code><span leaf="">         <span class="code-snippet__built_in">dispatch_state_machine</span>(<span class="code-snippet__number">3</span>, <span class="code-snippet__number">0x200000000000</span>);</span></code><br/><code><span leaf="">     }</span></code><br/><code><span leaf="">     <span class="code-snippet__keyword">else</span> <span class="code-snippet__keyword">if</span> (esr_gl1 == <span class="code-snippet__number">3</span>) {</span></code><br/><code><span leaf="">       <span class="code-snippet__keyword">if</span> (gl2_thread-&gt;unkown_flag != <span class="code-snippet__number">0</span>)</span></code><br/><code><span leaf="">         <span class="code-snippet__built_in">dead_loop</span>();</span></code><br/><code><span leaf="">         <span class="code-snippet__built_in">dispatch_state_machine</span>(<span class="code-snippet__number">4</span>, <span class="code-snippet__number">0x3000000000000</span>);</span></code><br/><code><span leaf="">       }</span></code><br/><code><span leaf="">       <span class="code-snippet__keyword">else</span> {</span></code><br/><code><span leaf="">         <span class="code-snippet__built_in">dead_loop</span>();</span></code><br/><code><span leaf="">     }</span></code><br/><code><span leaf="">   }</span></code><br/><code><span leaf="">}</span></code><br/></pre></p><p style=""><span lang="EN-US"><span leaf="">0x201420</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">可以触发如下调用路径，可以传递参数：</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="apache"><code><span leaf=""><span class="code-snippet__attribute">dispatch_state_machine</span>(<span class="code-snippet__number">2</span>, event_metadata);</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">dispatch_state_machine</span>(<span class="code-snippet__number">4</span>, event_metadata);</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">dispatch_state_machine</span>(<span class="code-snippet__number">3</span>, event_metadata);</span></code><br/></pre></p><p style=""><span lang="EN-US"><span leaf="">0x201421</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">可以触发如下调用路径，不能传递参数：</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="apache"><code><span leaf=""><span class="code-snippet__attribute">dispatch_state_machine</span>(<span class="code-snippet__number">0</span>xa, <span class="code-snippet__number">0</span>);</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">dispatch_state_machine</span>(<span class="code-snippet__number">8</span>, <span class="code-snippet__number">0</span>);</span></code><br/></pre></p><p style=""><span lang="EN-US"><span leaf="">0x201422</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">可以触发如下调用路径，不能传递参数：</span></span></p><p><span lang="EN-US"><span leaf="">dispatch_state_machine(3, 0x200000000000);</span></span></p><p style=""><span lang="EN-US"><span leaf="">0x201423</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">可以触发如下调用路径，不能传递参数：</span></span></p><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">dispatch_state_machine(4, 0x3000000000000);</span></span></p><h2><span lang="EN-US"><span leaf="">2.2 dispatch_state_machine</span></span><span style="font-family:
黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;"><span leaf="">分析</span></span></h2><p style=""><span lang="EN-US"><span leaf="">dispatch_state_machine</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">根据</span></span><span lang="EN-US"><span leaf="">sptm</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">的状态数据库</span></span><span lang="EN-US"><span leaf="">sptm_state_array</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">进行不同的操作。</span></span></p><p><span lang="EN-US"><span leaf="">sptm_state_array</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">是一个二维数组：</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="css"><code><span leaf="">sptm_state_struct {</span></code><br/><code><span leaf="">  dispatch_table_struct {</span></code><br/><code><span leaf="">    char next_state;</span></code><br/><code><span leaf="">    void *func_addr;</span></code><br/><code><span leaf="">    char domain_type;</span></code><br/><code><span leaf="">    +<span class="code-snippet__number">0</span>x18:</span></code><br/><code><span leaf="">      uint64_t unknown_value;</span></code><br/><code><span leaf="">    +<span class="code-snippet__number">0</span>x20:</span></code><br/><code><span leaf="">  }<span class="code-snippet__selector-attr">[12]</span>;</span></code><br/><code><span leaf="">  +<span class="code-snippet__number">0</span>x180:</span></code><br/><code><span leaf="">}<span class="code-snippet__selector-attr">[16]</span>;</span></code><br/></pre></p><p><span lang="EN-US"><span leaf="">    通过</span></span><span lang="EN-US"><span leaf="">gl2_thread-&gt;sptm_state</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">定位一维数组索引，通过第一个参数</span></span><span lang="EN-US"><span leaf="">event_type</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">定位二维数组索引。</span></span></p><p><span lang="EN-US" style="mso-no-proof:yes;"><span leaf=""><img data-aistatus="1" alt="1705907103518" class="rich_pages wxw-img" data-ratio="0.48148148148148145" data-type="png" data-w="1080" height="267" width="554" data-imgfileid="100000190" src="https://wechat2rss.xlab.app/img-proxy/?k=0143ed86&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_gif%2F4iaJia7Cvd3PCeibxXOIGLRw6XZ7fY9oXHBKDon91I7X7zNS9kU6hc3B9T0Elh4ySwa62JiaNjP3haYhrLTIQcCNQg%2F640%3Fwx_fmt%3Dgif%26from%3Dappmsg"/></span></span></p><p style=""><span lang="EN-US"><span leaf="">    Func_addr</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">为不同</span></span><span lang="EN-US"><span leaf="">sptm state</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">状态的驱动函数。</span></span></p><p><span lang="EN-US" style="mso-no-proof:yes;"><span leaf=""><img data-aistatus="1" alt="1705907377889" class="rich_pages wxw-img" data-ratio="0.06392199349945829" data-type="png" data-w="923" height="30" width="462" data-imgfileid="100000187" src="https://wechat2rss.xlab.app/img-proxy/?k=90c2a352&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_gif%2F4iaJia7Cvd3PCeibxXOIGLRw6XZ7fY9oXHB6OibE5XUCI9ZEDzIgU72DiaiayK83LEDECVVRaqYY5eh1wbdM7NVEHiaUA%2F640%3Fwx_fmt%3Dgif%26from%3Dappmsg"/></span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">    在对</span></span><span lang="EN-US"><span leaf="">sptm_state_array</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">这个庞大的状态数组进行分析后，得到了所有的状态驱动函数：</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="bash"><code><span leaf="">(gdb) p/x 0x598E0+0x180</span></code><br/><code><span leaf=""><span class="code-snippet__variable">$3</span> = 0x59a60</span></code><br/><code><span leaf="">(gdb) p/x 0x5D548+0x4000</span></code><br/><code><span leaf=""><span class="code-snippet__variable">$4</span> = 0x61548</span></code><br/><code><span leaf="">(gdb) p/x 0x5C370+0x4000</span></code><br/><code><span leaf=""><span class="code-snippet__variable">$5</span> = 0x60370</span></code><br/><code><span leaf="">(gdb) p/x 0x5D04C+0x4000</span></code><br/><code><span leaf=""><span class="code-snippet__variable">$6</span> = 0x6104c</span></code><br/><code><span leaf="">(gdb) p/x 0x5D098+0x4000</span></code><br/><code><span leaf=""><span class="code-snippet__variable">$7</span> = 0x61098</span></code><br/><code><span leaf="">(gdb) p/x 0x5CCFC+0x4000</span></code><br/><code><span leaf=""><span class="code-snippet__variable">$8</span> = 0x60cfc</span></code><br/><code><span leaf="">(gdb) p/x 0x5CD8C+0x4000</span></code><br/><code><span leaf=""><span class="code-snippet__variable">$9</span> = 0x60d8c</span></code><br/><code><span leaf="">(gdb) p/x 0x5C0E4+0x4000</span></code><br/><code><span leaf=""><span class="code-snippet__variable">$10</span> = 0x600e4</span></code><br/><code><span leaf="">(gdb) p/x 0x5D57C+0x4000</span></code><br/><code><span leaf=""><span class="code-snippet__variable">$11</span> = 0x6157c</span></code><br/><code><span leaf="">(gdb) p/x 0x5C47C+0x4000</span></code><br/><code><span leaf=""><span class="code-snippet__variable">$12</span> = 0x6047c</span></code><br/><code><span leaf="">(gdb) p/x 0x5C294+0x4000</span></code><br/><code><span leaf=""><span class="code-snippet__variable">$13</span> = 0x60294</span></code><br/><code><span leaf="">(gdb) p/x 0x5D44C+0x4000</span></code><br/><code><span leaf=""><span class="code-snippet__variable">$14</span> = 0x6144c</span></code><br/><code><span leaf="">(gdb) p/x 0x85DA0+0x4000</span></code><br/><code><span leaf=""><span class="code-snippet__variable">$15</span> = 0x89da0</span></code><br/><code><span leaf="">(gdb) p/x 0x5CEE0+0x4000</span></code><br/><code><span leaf=""><span class="code-snippet__variable">$16</span> = 0x60ee0</span></code><br/><code><span leaf="">(gdb) p/x 0x5C8E0+0x4000</span></code><br/><code><span leaf=""><span class="code-snippet__variable">$17</span> = 0x608e0</span></code><br/><code><span leaf="">(gdb) p/x 0x5D32C+0x4000</span></code><br/><code><span leaf=""><span class="code-snippet__variable">$18</span> = 0x6132c</span></code><br/><code><span leaf="">(gdb) p/x 0x5D364+0x4000</span></code><br/><code><span leaf=""><span class="code-snippet__variable">$19</span> = 0x61364</span></code><br/></pre></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">对其重新命名：</span></span></p><p><span lang="EN-US" style="mso-no-proof:yes;"><span leaf=""><img data-aistatus="1" alt="1705907543440" class="rich_pages wxw-img" data-ratio="0.7137614678899082" data-type="png" data-w="545" height="195" width="273" data-imgfileid="100000188" src="https://wechat2rss.xlab.app/img-proxy/?k=27112eaa&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_gif%2F4iaJia7Cvd3PCeibxXOIGLRw6XZ7fY9oXHBdpmsIsAvSiadwUJ6NOc6B9BliavPUXg3ah0YStF3dia7KBne2T2E7oibjg%2F640%3Fwx_fmt%3Dgif%26from%3Dappmsg"/></span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">    接着对参数</span></span><span lang="EN-US"><span leaf="">event_metadata</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">进行提取</span></span><span lang="EN-US"><span leaf="">domain_type</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">和</span></span><span lang="EN-US"><span leaf="">table_id</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，</span></span><span lang="EN-US"><span leaf="">event_metadata</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">的</span></span><span lang="EN-US"><span leaf="">48-53</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">位保存</span></span><span lang="EN-US"><span leaf="">domain_type</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，</span></span><span lang="EN-US"><span leaf=""> 32-39</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">保存</span></span><span lang="EN-US"><span leaf="">table_id</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。</span></span></p><p><span lang="EN-US" style="mso-no-proof:yes;"><span leaf=""><img data-aistatus="1" alt="1705907904374" class="rich_pages wxw-img" data-ratio="0.6462962962962963" data-type="png" data-w="1080" height="358" width="553" data-imgfileid="100000191" src="https://wechat2rss.xlab.app/img-proxy/?k=ae295342&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_gif%2F4iaJia7Cvd3PCeibxXOIGLRw6XZ7fY9oXHBmaZthbZY2C2KjiaXgOiaw6RWXttTQYlxLrYPXrecFvJB1xCvRgtXYdJA%2F640%3Fwx_fmt%3Dgif%26from%3Dappmsg"/></span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">然后测试提取出的</span></span><span lang="EN-US"><span leaf="">domain_type</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">有没有这个</span></span><span lang="EN-US"><span leaf="">table_id</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">的对应权限。</span></span></p><p><span lang="EN-US" style="mso-no-proof:yes;"><span leaf=""><img data-aistatus="1" alt="1705907997927" class="rich_pages wxw-img" data-ratio="0.1583880037488285" data-type="png" data-w="1067" height="85" width="534" data-imgfileid="100000189" src="https://wechat2rss.xlab.app/img-proxy/?k=a4b481a4&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_gif%2F4iaJia7Cvd3PCeibxXOIGLRw6XZ7fY9oXHBwxEk6q41ofpgjanozg6niay5icrKEHXT2z8HYTfdmqvBlxqqtBxPXBoQ%2F640%3Fwx_fmt%3Dgif%26from%3Dappmsg"/></span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">    最终提取的是</span></span><span lang="EN-US"><span leaf="">table_id_struct</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">里的</span></span><span lang="EN-US"><span leaf="">entry_point</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">函数，接着调用</span></span><span lang="EN-US"><span leaf="">sptm state</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">的驱动函数，将这个</span></span><span lang="EN-US"><span leaf="">entry_point</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">作为回调参数：</span></span></p><p><span lang="EN-US" style="mso-no-proof:yes;"><span leaf=""><img data-aistatus="1" alt="1705908248510" class="rich_pages wxw-img" data-ratio="0.12197392923649907" data-type="png" data-w="1074" height="68" width="554" data-imgfileid="100000195" src="https://wechat2rss.xlab.app/img-proxy/?k=7073a702&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_gif%2F4iaJia7Cvd3PCeibxXOIGLRw6XZ7fY9oXHBUkDgBaKhicQScQTAOQuHria1lUSIx0u1eatw2SGM1SUhW0VXW4RicyS6Q%2F640%3Fwx_fmt%3Dgif%26from%3Dappmsg"/></span></span></p><p style=""><span lang="EN-US"><span leaf="">    Entry_point</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">在</span></span><span lang="EN-US"><span leaf="">sptm</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">启动阶段通过</span></span><span lang="EN-US"><span leaf="">sptm_register_dispatch_table</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">进行了注册：</span></span></p><p><span lang="EN-US" style="mso-no-proof:yes;"><span leaf=""><img data-aistatus="1" alt="1705908414664" class="rich_pages wxw-img" data-ratio="0.45083487940630795" data-type="png" data-w="1078" height="250" width="554" data-imgfileid="100000196" src="https://wechat2rss.xlab.app/img-proxy/?k=9592bdc9&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_gif%2F4iaJia7Cvd3PCeibxXOIGLRw6XZ7fY9oXHB1X5wnb33SKPbFnhLdgpg8wPbDvSfBx1nibhBU55BBvWTpae8ZMXckww%2F640%3Fwx_fmt%3Dgif%26from%3Dappmsg"/></span></span></p><p style=""><span lang="EN-US"><span leaf="">    IOMMU</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">子系统也进行了对应的注册：</span></span></p><p><span lang="EN-US" style="mso-no-proof:yes;"><span leaf=""><img data-aistatus="1" alt="1705908502322" class="rich_pages wxw-img" data-ratio="0.15004840271055178" data-type="png" data-w="1033" height="78" width="517" data-imgfileid="100000194" src="https://wechat2rss.xlab.app/img-proxy/?k=f86b2387&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_gif%2F4iaJia7Cvd3PCeibxXOIGLRw6XZ7fY9oXHBKZq6dGcxTMDZbQc6LzjZA2hs3mdneRjYSHsiceAosDqBYWqVN1sKyTg%2F640%3Fwx_fmt%3Dgif%26from%3Dappmsg"/></span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf=""> 在</span></span><span lang="EN-US"><span leaf="">iommu_register_dispatch_table</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">函数内部也是将</span></span><span lang="EN-US"><span leaf="">sptm_dispatch</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">作为</span></span><span lang="EN-US"><span leaf="">entry_point</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">进行注册：</span></span></p><p><span lang="EN-US" style="mso-no-proof:yes;"><span leaf=""><img data-aistatus="1" alt="1705908570552" class="rich_pages wxw-img" data-ratio="0.21984216459977451" data-type="png" data-w="887" height="98" width="444" data-imgfileid="100000193" src="https://wechat2rss.xlab.app/img-proxy/?k=e4c8d1e0&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_gif%2F4iaJia7Cvd3PCeibxXOIGLRw6XZ7fY9oXHBSDjwu2z7rPUZh5wia6TicmgGGRHZDOU3weZl3hQibLPuicOrTz1h6F3CmQ%2F640%3Fwx_fmt%3Dgif%26from%3Dappmsg"/></span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">   在分析</span></span><span lang="EN-US"><span leaf="">Sptm_dispatch</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">之前，还需要弄清</span></span><span lang="EN-US"><span leaf="">sptm state</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">驱动函数在何时调用</span></span><span lang="EN-US"><span leaf="">sptm_dispatch</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。</span></span></p><p style=""><span lang="EN-US"><span leaf="">Sptm</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">在不同的状态将会调用不同的驱动函数，</span></span><span lang="EN-US"><span leaf="">sptm_state_func1</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">函数只会将</span></span><span lang="EN-US"><span leaf="">elr_gl1</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">设置为</span></span><span lang="EN-US"><span leaf="">elr_gl1_cl4</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，返回</span></span><span lang="EN-US"><span leaf="">gl0</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">运行，不会调用</span></span><span lang="EN-US"><span leaf="">sptm_dispatch</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。</span></span><span lang="EN-US"><span leaf="">sptm_state_func2</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">函数同上，在</span></span><span lang="EN-US"><span leaf="">gl0</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">运行</span></span><span lang="EN-US"><span leaf="">elr_gl1_txm</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。而</span></span><span lang="EN-US"><span leaf="">sptm_state_func3</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">函数才会在</span></span><span lang="EN-US"><span leaf="">gl2</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">调用</span></span><span lang="EN-US"><span leaf="">sptm_dispatch:</span></span></p><p><span lang="EN-US" style="mso-no-proof:yes;"><span leaf=""><img data-aistatus="1" alt="1705909920023" class="rich_pages wxw-img" data-ratio="0.10138740661686232" data-type="png" data-w="937" height="48" width="469" data-imgfileid="100000192" src="https://wechat2rss.xlab.app/img-proxy/?k=a4ef6d5c&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_gif%2F4iaJia7Cvd3PCeibxXOIGLRw6XZ7fY9oXHB4l6eqibJnvGibHNSPWpEyEPJxrLO6laeHc4Y7nqzOx2HrE4icXgKiadkibw%2F640%3Fwx_fmt%3Dgif%26from%3Dappmsg"/></span></span></p><p style=""><span lang="EN-US"><span leaf="">    X1</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">就是驱动函数的第</span></span><span lang="EN-US"><span leaf="">2</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">个参数，即</span></span><span lang="EN-US"><span leaf="">sptm_dispatch</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。</span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">而</span></span><span lang="EN-US"><span leaf="">sptm_state_func8</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">比较有意思，它将</span></span><span lang="EN-US"><span leaf="">sptm_dispatch</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">放到了</span></span><span lang="EN-US"><span leaf="">gl0</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">运行：</span></span></p><p><span lang="EN-US" style="mso-no-proof:yes;"><span leaf=""><img data-aistatus="1" alt="1705912645964" class="rich_pages wxw-img" data-ratio="0.14007421150278293" data-type="png" data-w="1078" height="78" width="554" data-imgfileid="100000198" src="https://wechat2rss.xlab.app/img-proxy/?k=944a01e3&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_gif%2F4iaJia7Cvd3PCeibxXOIGLRw6XZ7fY9oXHBicWUjH9OriaLBicCG1ZrtsaBc5xADIPLsW1ILdjWGic5WnmBibdm9bVia9jg%2F640%3Fwx_fmt%3Dgif%26from%3Dappmsg"/></span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">    完整的</span></span><span lang="EN-US"><span leaf="">dispatch_state_machine</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">函数如下：</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf=""><span class="code-snippet__function"><span class="code-snippet__type">void</span></span><span class="code-snippet__function"><span class="code-snippet__title">dispatch_state_machine</span></span><span class="code-snippet__function"><span class="code-snippet__params">(</span></span><span class="code-snippet__function"><span class="code-snippet__params"><span class="code-snippet__type">char</span></span></span><span class="code-snippet__function"><span class="code-snippet__params"> event_type, </span></span><span class="code-snippet__function"><span class="code-snippet__params"><span class="code-snippet__type">uint64_t</span></span></span><span class="code-snippet__function"><span class="code-snippet__params"> event_metadata)</span></span></span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf="">   <span class="code-snippet__built_in">check_GXF_STATUS_EL1</span>();</span></code><br/><code><span leaf="">   <span class="code-snippet__keyword">if</span> (gl2_thread-&gt;stpm_state &gt; <span class="code-snippet__number">0x11</span>)</span></code><br/><code><span leaf="">     <span class="code-snippet__built_in">invalid_state_branch</span>();</span></code><br/><code><span leaf="">   <span class="code-snippet__keyword">if</span> (event_type &gt; <span class="code-snippet__number">0xc</span>)</span></code><br/><code><span leaf="">     <span class="code-snippet__built_in">invalid_event_type_branch</span>();</span></code><br/><code></code><br/><code><span leaf="">     <span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">sptm_state_struct</span> *sptm_state = sptm_state_array[gl2_thread-&gt;sptm_state * <span class="code-snippet__number">0x180</span>];</span></code><br/><code><span leaf="">     <span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">dispatch_table_struct</span> *target_elem = sptm_state_array[gl2_thread-&gt;sptm_state * <span class="code-snippet__number">0x180</span>][event_type * <span class="code-snippet__number">32</span>];</span></code><br/><code><span leaf="">     <span class="code-snippet__keyword">if</span> (target_elem-&gt;next_state &gt; <span class="code-snippet__number">0x11</span>)</span></code><br/><code><span leaf="">         <span class="code-snippet__built_in">invalid_next_state_branch</span>();</span></code><br/><code><span leaf="">     <span class="code-snippet__keyword">if</span> (!target_elem-&gt;func_addr)</span></code><br/><code><span leaf="">         <span class="code-snippet__built_in">invalid_state_transition_branch</span>();</span></code><br/><code><span leaf="">     gl2_thread-&gt;domain_type = target_elem-&gt;domain_type;</span></code><br/><code><span leaf="">     <span class="code-snippet__keyword">if</span> (!(target_elem-&gt;unknown_value &amp; <span class="code-snippet__number">0x1</span>)) {</span></code><br/><code><span leaf="">       <span class="code-snippet__keyword">if</span> (!(target_elem-&gt;unknown_value &amp; <span class="code-snippet__number">0x2</span>)) {</span></code><br/><code><span leaf="">         gl2_thread-&gt;sptm_state = target_elem-&gt;next_state;</span></code><br/><code><span leaf="">         target_elem-&gt;<span class="code-snippet__built_in">func_addr</span>(event_metadata, <span class="code-snippet__literal">NULL</span>);</span></code><br/><code><span leaf="">       }</span></code><br/><code><span leaf="">       <span class="code-snippet__keyword">else</span> {</span></code><br/><code><span leaf="">         <span class="code-snippet__keyword">if</span> (gl2_thread-&gt;hop_flag != <span class="code-snippet__number">1</span>)</span></code><br/><code><span leaf="">           <span class="code-snippet__built_in">invalid_hop_detected_branch</span>();</span></code><br/><code></code><br/><code><span leaf="">           <span class="code-snippet__built_in">dispatch_err_log</span>();</span></code><br/><code><span leaf="">       }</span></code><br/><code><span leaf="">   }</span></code><br/><code><span leaf="">   <span class="code-snippet__keyword">else</span> {</span></code><br/><code><span leaf="">     <span class="code-snippet__keyword">if</span> (event_metadata &amp; <span class="code-snippet__number">0xFC000000000000</span>)</span></code><br/><code><span leaf="">         <span class="code-snippet__built_in">domain_id_branch</span>();</span></code><br/><code><span leaf="">     <span class="code-snippet__keyword">if</span> (event_metadata &amp; <span class="code-snippet__number">0xF000000000</span>)</span></code><br/><code><span leaf="">         <span class="code-snippet__built_in">table_id_branch</span>();   </span></code><br/><code><span leaf="">      <span class="code-snippet__type">uint64_t</span> domain_id_index = (event_metadata &gt;&gt; <span class="code-snippet__number">48</span>) &amp; <span class="code-snippet__number">0xff</span> - <span class="code-snippet__number">1</span>;</span></code><br/><code><span leaf="">      <span class="code-snippet__type">uint64_t</span> table_id_index = (event_metadata &gt;&gt; <span class="code-snippet__number">32</span>) &amp; <span class="code-snippet__number">0xff</span></span></code><br/><code><span leaf="">     <span class="code-snippet__keyword">if</span> (domain_id &gt; <span class="code-snippet__number">1</span>) {</span></code><br/><code><span leaf="">       <span class="code-snippet__keyword">struct</span> domain_id_struct *domain_id = domain_id_array[domain_id_index];</span></code><br/><code><span leaf="">       <span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">table_id_struct</span> *table_id = domain_id_array[domain_id_index][table_id_index * <span class="code-snippet__number">0x18</span>];</span></code><br/><code><span leaf="">     }</span></code><br/><code><span leaf="">     <span class="code-snippet__keyword">else</span> {</span></code><br/><code><span leaf="">       <span class="code-snippet__keyword">struct</span> domain_id_struct *domain_id = domain_id_array[domain_id_index];</span></code><br/><code><span leaf="">       <span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">table_id_struct</span> *table_id = domain_id_array[domain_id_index][table_id_index * <span class="code-snippet__number">0x18</span>];</span></code><br/><code><span leaf="">   }</span></code><br/><code><span leaf="">   <span class="code-snippet__keyword">if</span> (!(table_id-&gt;table_permissions &gt;&gt; gl2_thread-&gt;caller_domain) &amp; <span class="code-snippet__number">0x1</span>))</span></code><br/><code><span leaf="">     <span class="code-snippet__built_in">table_permissions_branch</span>();</span></code><br/><code><span leaf="">     <span class="code-snippet__keyword">if</span> (table_id-&gt;entry_point == <span class="code-snippet__number">0</span>)</span></code><br/><code><span leaf="">       <span class="code-snippet__built_in">illegal_dispatch_branch</span>();</span></code><br/><code><span leaf="">     <span class="code-snippet__keyword">if</span> (!(target_elem-&gt;unknown_value &amp; <span class="code-snippet__number">0x2</span>)) {</span></code><br/><code><span leaf="">       gl2_thread-&gt;sptm_state = target_elem-&gt;next_state;</span></code><br/><code><span leaf="">       target_elem-&gt;<span class="code-snippet__built_in">func_addr</span>(event_metadata, table_id-&gt;entry_point);</span></code><br/><code><span leaf="">   }</span></code><br/><code><span leaf="">   <span class="code-snippet__keyword">else</span> {</span></code><br/><code><span leaf="">     <span class="code-snippet__keyword">if</span> (gl2_thread-&gt;hop_flag != <span class="code-snippet__number">1</span>)</span></code><br/><code><span leaf="">       <span class="code-snippet__built_in">invalid_hop_detected_branch</span>();</span></code><br/><code></code><br/><code><span leaf="">       <span class="code-snippet__built_in">dispatch_err_log</span>();</span></code><br/><code><span leaf="">     }</span></code><br/><code><span leaf="">   }</span></code><br/><code><span leaf="">}</span></code><br/></pre></p><h2><span lang="EN-US"><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">2.3 sptm_dispatch</span></span></span></h2><p style=""><span lang="EN-US"><span leaf="">sptm</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">注册了</span></span><span lang="EN-US"><span leaf="">7</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">个子系统，每个子系统都有一个</span></span><span lang="EN-US"><span leaf="">dispatch table</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。</span></span></p><table style="border-collapse:collapse;border:none;mso-border-alt:solid windowtext .5pt;mso-yfti-tbllook:1184;mso-padding-alt:0cm 5.4pt 0cm 5.4pt;"><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col style="width: 189px;"/><col style="width: 189px;"/><col style="width: 189px;"/></colgroup><tbody><tr style="mso-yfti-irow:0;mso-yfti-firstrow:yes;"><td data-colwidth="189" width="189" valign="top" style="border: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">编号</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: 1pt solid windowtext;border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-image: initial;border-left: none;padding: 0cm 5.4pt;"><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">子系统名称</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: 1pt solid windowtext;border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-image: initial;border-left: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">Dispatch table</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
  minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">函数表数目</span></span></p></td></tr><tr style="mso-yfti-irow:1;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">0</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">Xnu</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">22</span></span></p></td></tr><tr style="mso-yfti-irow:2;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">1</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">txm</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">5</span></span></p></td></tr><tr style="mso-yfti-irow:3;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">2</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">unknown</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">3</span></span></p></td></tr><tr style="mso-yfti-irow:4;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">3</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">dart</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">17</span></span></p></td></tr><tr style="mso-yfti-irow:5;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">4</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">unknown</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">2</span></span></p></td></tr><tr style="mso-yfti-irow:6;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">5</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">sart</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">3</span></span></p></td></tr><tr style="mso-yfti-irow:7;mso-yfti-lastrow:yes;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">6</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">uat</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">13</span></span></p></td></tr></tbody></table><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">函数原型：</span></span><span lang="EN-US"><span leaf="">sptm_dispatch(uint64_t event_metadata)</span></span></p><p style=""><span lang="EN-US"><span leaf="">event_metadata</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">的</span></span><span lang="EN-US"><span leaf="">32-39</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">位保存的是</span></span><span lang="EN-US"><span leaf="">dispatch table</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">表中的索引。</span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">使用以下脚本将</span></span><span lang="EN-US"><span leaf="">table</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">表中的值转为对应的函数地址：</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="apache"><code><span leaf=""><span class="code-snippet__attribute">awk</span> &#39;{print $<span class="code-snippet__number">3</span>}&#39; c.txt|sed -e &#39;s/<span class="code-snippet__number">8</span>[<span class="code-snippet__number">0</span>-<span class="code-snippet__number">9</span>][<span class="code-snippet__number">0</span>-<span class="code-snippet__number">9</span>]/<span class="code-snippet__number">0</span>/&#39; |awk &#39;{a=strtonum($<span class="code-snippet__number">1</span>)+<span class="code-snippet__number">0</span>x4000+<span class="code-snippet__number">0</span>x7000000; printf(<span class="code-snippet__string">&#34;%d 0xfffffff0%08x\n&#34;</span>, NR, a)}&#39;</span></code></pre></p><table style="border-collapse:collapse;border:none;mso-border-alt:solid windowtext .5pt;mso-yfti-tbllook:1184;mso-padding-alt:0cm 5.4pt 0cm 5.4pt;"><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col style="width: 189px;"/><col style="width: 189px;"/><col style="width: 189px;"/></colgroup><tbody><tr style="mso-yfti-irow:0;mso-yfti-firstrow:yes;"><td data-colwidth="189" width="189" valign="top" style="border: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">XNU</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: 1pt solid windowtext;border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-image: initial;border-left: none;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
  minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">函数地址</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: 1pt solid windowtext;border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-image: initial;border-left: none;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
  minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">函数名</span></span></p></td></tr><tr style="mso-yfti-irow:1;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">1</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">0xfffffff007072b9c</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">unknown</span></span></p></td></tr><tr style="mso-yfti-irow:2;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">2</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">0xfffffff00708a2ec</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">sptm_retype</span></span></p></td></tr><tr style="mso-yfti-irow:3;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">3</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">0xfffffff00708a824</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">sptm_map_page</span></span></p></td></tr><tr style="mso-yfti-irow:4;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">4</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">0xfffffff00708b2d8</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">sptm_map_table</span></span></p></td></tr><tr style="mso-yfti-irow:5;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">5</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">0xfffffff00708ba34</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">sptm_unmap_table</span></span></p></td></tr><tr style="mso-yfti-irow:6;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">6</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">0xfffffff00708cd58</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">sptm_update_region</span></span></p></td></tr><tr style="mso-yfti-irow:7;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">7</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">0xfffffff00708d350</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">sptm_update_disjoint</span></span></p></td></tr><tr style="mso-yfti-irow:8;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">8</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">0xfffffff00708c95c</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">sptm_unmap_region</span></span></p></td></tr><tr style="mso-yfti-irow:9;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">9</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">0xfffffff00708d3f0</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">sptm_unmap_disjoint</span></span></p></td></tr><tr style="mso-yfti-irow:10;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">10</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">0xfffffff00708d830</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">sptm_shared_region_configure</span></span></p></td></tr><tr style="mso-yfti-irow:11;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">11</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">0xfffffff00708db74</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">sptm_nest_region</span></span></p></td></tr><tr style="mso-yfti-irow:12;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">12</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">0xfffffff00708e2bc</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">sptm_unnest_region</span></span></p></td></tr><tr style="mso-yfti-irow:13;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">13</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">0xfffffff00708e6f8</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">sptm_validate_root_config</span></span></p></td></tr><tr style="mso-yfti-irow:14;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">14</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">0xfffffff00708e7d4</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">sptm_generate_rtlbi_param</span></span></p></td></tr><tr style="mso-yfti-irow:15;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">15</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">0xfffffff0070730ac</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">sptm_register_cpu</span></span></p></td></tr><tr style="mso-yfti-irow:16;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">16</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">0xfffffff007075114</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">sptm_register_type</span></span></p></td></tr><tr style="mso-yfti-irow:17;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">17</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">0xfffffff00708ec94</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">sptm_sign_user_pointer</span></span></p></td></tr><tr style="mso-yfti-irow:18;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">18</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">0xfffffff00708ed54</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">sptm_auth_user_pointer</span></span></p></td></tr><tr style="mso-yfti-irow:19;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">19</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">0xfffffff00708a020</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">sptm_register_xnu_exception_return</span></span></p></td></tr><tr style="mso-yfti-irow:20;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">20</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">0xfffffff007073814</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">sptm_cpu_unknown_func</span></span></p></td></tr><tr style="mso-yfti-irow:21;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">21</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">0xfffffff007073530</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">sptm_slide_region</span></span></p></td></tr><tr style="mso-yfti-irow:22;mso-yfti-lastrow:yes;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">22</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">0xfffffff00708d428</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">sptm_update_papt</span></span></p></td></tr></tbody></table><table style="border-collapse:collapse;border:none;mso-border-alt:solid windowtext .5pt;mso-yfti-tbllook:1184;mso-padding-alt:0cm 5.4pt 0cm 5.4pt;"><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col style="width: 189px;"/><col style="width: 189px;"/><col style="width: 189px;"/></colgroup><tbody><tr style="mso-yfti-irow:0;mso-yfti-firstrow:yes;"><td data-colwidth="189" width="189" valign="top" style="border: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US" style="font-size:
  10.5pt;mso-bidi-font-size:12.0pt;mso-font-kerning:1.0pt;"><span leaf="">txm</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: 1pt solid windowtext;border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-image: initial;border-left: none;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span style="font-size:10.5pt;mso-bidi-font-size:12.0pt;font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-font-kerning:
  1.0pt;"><span leaf="">函数地址</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: 1pt solid windowtext;border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-image: initial;border-left: none;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span style="font-size:10.5pt;mso-bidi-font-size:12.0pt;font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-font-kerning:
  1.0pt;"><span leaf="">函数名称</span></span></p></td></tr><tr style="mso-yfti-irow:1;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US" style="font-size:
  10.5pt;mso-bidi-font-size:12.0pt;mso-font-kerning:1.0pt;"><span leaf="">1</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US" style="font-size:
  10.5pt;mso-bidi-font-size:12.0pt;mso-font-kerning:1.0pt;"><span leaf="">0xfffffff0070751cc</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:2;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US" style="font-size:
  10.5pt;mso-bidi-font-size:12.0pt;mso-font-kerning:1.0pt;"><span leaf="">2</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US" style="font-size:
  10.5pt;mso-bidi-font-size:12.0pt;mso-font-kerning:1.0pt;"><span leaf="">0xfffffff007089e60</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US" style="font-size:
  10.5pt;mso-bidi-font-size:12.0pt;mso-font-kerning:1.0pt;"><span leaf="">sptm_register_dispatch_table</span></span></p></td></tr><tr style="mso-yfti-irow:3;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US" style="font-size:
  10.5pt;mso-bidi-font-size:12.0pt;mso-font-kerning:1.0pt;"><span leaf="">3</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US" style="font-size:
  10.5pt;mso-bidi-font-size:12.0pt;mso-font-kerning:1.0pt;"><span leaf="">0xfffffff00708a2ec</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US" style="font-size:
  10.5pt;mso-bidi-font-size:12.0pt;mso-font-kerning:1.0pt;"><span leaf="">sptm_retype</span></span></p></td></tr><tr style="mso-yfti-irow:4;mso-yfti-lastrow:yes;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US" style="font-size:
  10.5pt;mso-bidi-font-size:12.0pt;mso-font-kerning:1.0pt;"><span leaf="">4</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="mso-pagination:widow-orphan;"><span lang="EN-US" style="font-size:
  10.5pt;mso-bidi-font-size:12.0pt;mso-font-kerning:1.0pt;"><span leaf="">0xfffffff00708ee28</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr></tbody></table><table style="border-collapse:collapse;border:none;mso-border-alt:solid windowtext .5pt;mso-yfti-tbllook:1184;mso-padding-alt:0cm 5.4pt 0cm 5.4pt;"><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col style="width: 189px;"/><col style="width: 189px;"/><col style="width: 189px;"/></colgroup><tbody><tr style="mso-yfti-irow:0;mso-yfti-firstrow:yes;"><td data-colwidth="189" width="189" valign="top" style="border: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">Unknown</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: 1pt solid windowtext;border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-image: initial;border-left: none;padding: 0cm 5.4pt;"><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">函数地址</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: 1pt solid windowtext;border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-image: initial;border-left: none;padding: 0cm 5.4pt;"><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">函数名称</span></span></p></td></tr><tr style="mso-yfti-irow:1;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">1</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">0xfffffff007089e60</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">sptm_register_dispatch_table</span></span></p></td></tr><tr style="mso-yfti-irow:2;height:15.25pt;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;height: 15.25pt;"><p><span lang="EN-US"><span leaf="">2</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;height: 15.25pt;"><p><span lang="EN-US"><span leaf="">0xfffffff00708a2ec</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;height: 15.25pt;"><p><span lang="EN-US"><span leaf="">sptm_retype</span></span></p></td></tr><tr style="mso-yfti-irow:3;mso-yfti-lastrow:yes;height:15.25pt;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;height: 15.25pt;"><p><span lang="EN-US"><span leaf="">3</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;height: 15.25pt;"><p><span lang="EN-US"><span leaf="">0xfffffff0070878f8</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;height: 15.25pt;"></td></tr></tbody></table><table style="border-collapse:collapse;border:none;mso-border-alt:solid windowtext .5pt;mso-yfti-tbllook:1184;mso-padding-alt:0cm 5.4pt 0cm 5.4pt;"><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col style="width: 189px;"/><col style="width: 189px;"/><col style="width: 189px;"/></colgroup><tbody><tr style="mso-yfti-irow:0;mso-yfti-firstrow:yes;"><td data-colwidth="189" width="189" valign="top" style="border: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">dart</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: 1pt solid windowtext;border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-image: initial;border-left: none;padding: 0cm 5.4pt;"><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">函数地址</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: 1pt solid windowtext;border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-image: initial;border-left: none;padding: 0cm 5.4pt;"><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">函数名称</span></span></p></td></tr><tr style="mso-yfti-irow:1;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">1</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">0xfffffff00707dee0</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:2;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">2</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">0xfffffff00707d498</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:3;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">3</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">0xfffffff00707cdec</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:4;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">4</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">0xfffffff00707c1bc</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:5;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">5</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">0xfffffff00707bdf4</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:6;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">6</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">0xfffffff00707aeb4</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:7;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">7</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">0xfffffff007079e0c</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:8;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">8</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">0xfffffff007079b54</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:9;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">9</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">0xfffffff0070798d8</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:10;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">10</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">0xfffffff00707962c</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:11;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">11</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">0xfffffff0070794f4</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:12;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">12</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">0xfffffff007079358</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:13;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">13</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">0xfffffff007079068</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:14;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">14</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">0xfffffff007078e8c</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:15;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">15</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">0xfffffff007078ca8</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:16;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">16</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">0xfffffff007078a60</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:17;mso-yfti-lastrow:yes;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">17</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">0xfffffff007078044</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr></tbody></table><table style="border-collapse:collapse;border:none;mso-border-alt:solid windowtext .5pt;mso-yfti-tbllook:1184;mso-padding-alt:0cm 5.4pt 0cm 5.4pt;"><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col style="width: 189px;"/><col style="width: 189px;"/><col style="width: 189px;"/></colgroup><tbody><tr style="mso-yfti-irow:0;mso-yfti-firstrow:yes;"><td data-colwidth="189" width="189" valign="top" style="border: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">Unknown</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: 1pt solid windowtext;border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-image: initial;border-left: none;padding: 0cm 5.4pt;"><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">函数地址</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: 1pt solid windowtext;border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-image: initial;border-left: none;padding: 0cm 5.4pt;"><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">函数名称</span></span></p></td></tr><tr style="mso-yfti-irow:1;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">1</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">0xfffffff00707e928</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:2;mso-yfti-lastrow:yes;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">2</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">0xfffffff00707e800</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr></tbody></table><table style="border-collapse:collapse;border:none;mso-border-alt:solid windowtext .5pt;mso-yfti-tbllook:1184;mso-padding-alt:0cm 5.4pt 0cm 5.4pt;"><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col style="width: 189px;"/><col style="width: 189px;"/><col style="width: 189px;"/></colgroup><tbody><tr style="mso-yfti-irow:0;mso-yfti-firstrow:yes;"><td data-colwidth="189" width="189" valign="top" style="border: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">sart</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: 1pt solid windowtext;border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-image: initial;border-left: none;padding: 0cm 5.4pt;"><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">函数地址</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: 1pt solid windowtext;border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-image: initial;border-left: none;padding: 0cm 5.4pt;"><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">函数名称</span></span></p></td></tr><tr style="mso-yfti-irow:1;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">1</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">0xfffffff00707791c</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:2;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">2</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">0xfffffff0070774dc</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:3;mso-yfti-lastrow:yes;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">3</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">0xfffffff007077000</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr></tbody></table><table style="border-collapse:collapse;border:none;mso-border-alt:solid windowtext .5pt;mso-yfti-tbllook:1184;mso-padding-alt:0cm 5.4pt 0cm 5.4pt;"><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col style="width: 189px;"/><col style="width: 189px;"/><col style="width: 189px;"/></colgroup><tbody><tr style="mso-yfti-irow:0;mso-yfti-firstrow:yes;"><td data-colwidth="189" width="189" valign="top" style="border: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">nvme</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: 1pt solid windowtext;border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-image: initial;border-left: none;padding: 0cm 5.4pt;"><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">函数地址</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: 1pt solid windowtext;border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-image: initial;border-left: none;padding: 0cm 5.4pt;"><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">函数名称</span></span></p></td></tr><tr style="mso-yfti-irow:1;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">1</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">0xfffffff007076078</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:2;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">2</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">0xfffffff0070759e4</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:3;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">3</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">0xfffffff0070756fc</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:4;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">4</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">0xfffffff0070754c0</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:5;mso-yfti-lastrow:yes;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">5</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">0xfffffff007075000</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr></tbody></table><table style="border-collapse:collapse;border:none;mso-border-alt:solid windowtext .5pt;mso-yfti-tbllook:1184;mso-padding-alt:0cm 5.4pt 0cm 5.4pt;"><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col/></colgroup><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><tfoot><tr><td></td></tr></tfoot></table><table><caption></caption><colgroup><col style="width: 189px;"/><col style="width: 189px;"/><col style="width: 189px;"/></colgroup><tbody><tr style="mso-yfti-irow:0;mso-yfti-firstrow:yes;"><td data-colwidth="189" width="189" valign="top" style="border: 1pt solid windowtext;padding: 0cm 5.4pt;"><p style="text-align:left;tab-stops:256.05pt;"><span lang="EN-US"><span leaf="">uat</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: 1pt solid windowtext;border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-image: initial;border-left: none;padding: 0cm 5.4pt;"><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">函数地址</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: 1pt solid windowtext;border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-image: initial;border-left: none;padding: 0cm 5.4pt;"><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">函数名称</span></span></p></td></tr><tr style="mso-yfti-irow:1;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">1</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">0xfffffff0070718ec</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:2;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">2</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">0xfffffff0070716e8</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:3;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">3</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">0xfffffff00707135c</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:4;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">4</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">0xfffffff0070710c8</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:5;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">5</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">0xfffffff007070fdc</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:6;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">6</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">0xfffffff007070978</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:7;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">7</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">0xfffffff0070707c0</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:8;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">8</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">0xfffffff0070704d4</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:9;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">9</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">0xfffffff007070190</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:10;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">10</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">0xfffffff00706f628</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:11;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">11</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">0xfffffff00706f340</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:12;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">12</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">0xfffffff00706eb14</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr><tr style="mso-yfti-irow:13;mso-yfti-lastrow:yes;"><td data-colwidth="189" width="189" valign="top" style="border-right: 1pt solid windowtext;border-bottom: 1pt solid windowtext;border-left: 1pt solid windowtext;border-image: initial;border-top: none;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">13</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"><p><span lang="EN-US"><span leaf="">0xfffffff00706e97c</span></span></p></td><td data-colwidth="189" width="189" valign="top" style="border-top: none;border-left: none;border-bottom: 1pt solid windowtext;border-right: 1pt solid windowtext;padding: 0cm 5.4pt;"></td></tr></tbody></table><p style="mso-pagination:widow-orphan;"><span lang="EN-US" style="mso-no-proof:
yes;"><span leaf=""><img data-aistatus="1" alt="1705915630067" class="rich_pages wxw-img" data-ratio="0.55" data-type="png" data-w="640" height="305" width="554" data-imgfileid="100000201" src="https://wechat2rss.xlab.app/img-proxy/?k=789d5d69&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_gif%2F4iaJia7Cvd3PCeibxXOIGLRw6XZ7fY9oXHBwWzQnUNUrGLwZSzLXR5ibwXCrqNWPwTp4XibZZZITicicQaOiayXMY0zBBw%2F640%3Fwx_fmt%3Dgif%26from%3Dappmsg"/></span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">不同的</span></span><span lang="EN-US"><span leaf="">switch case</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">最后统一调用</span></span><span lang="EN-US"><span leaf="">sptm_dispatch_entry_point</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">函数：</span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">函数原型：</span></span><span lang="EN-US"><span leaf="">sptm_dispatch_entry_point(uint64_t table_entry_point)</span></span></p><p style="mso-pagination:widow-orphan;"><span lang="EN-US" style="mso-no-proof:
yes;"><span leaf=""><img data-aistatus="1" alt="1705925859826" class="rich_pages wxw-img" data-ratio="0.1765625" data-type="png" data-w="640" height="98" width="554" data-imgfileid="100000199" src="https://wechat2rss.xlab.app/img-proxy/?k=e83711a9&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_gif%2F4iaJia7Cvd3PCeibxXOIGLRw6XZ7fY9oXHBLmdd37MfjB6kDlS8wSIiaeOfzWTicEGpeWDoquhnvEEVqFtpvLBoaFYw%2F640%3Fwx_fmt%3Dgif%26from%3Dappmsg"/></span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">    首先从</span></span><span lang="EN-US"><span leaf="">gl2_thread</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">中恢复</span></span><span lang="EN-US"><span leaf="">sptm_dispatch</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">需要的各种参数，这些参数在</span></span><span lang="EN-US"><span leaf="">gxf_entry_el1</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">开始处进行了保存。</span></span></p><p style=""><span lang="EN-US" style="mso-no-proof:yes;"><span leaf=""><img data-aistatus="1" alt="1705926019600" class="rich_pages wxw-img" data-ratio="0.0328125" data-type="png" data-w="640" height="18" width="538" data-imgfileid="100000197" src="https://wechat2rss.xlab.app/img-proxy/?k=51a717e9&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_gif%2F4iaJia7Cvd3PCeibxXOIGLRw6XZ7fY9oXHBGm3fAMrCCzdL94xQlcX9uibXxxvricVpTNcmPsKeMaNZSHotJptKKCHw%2F640%3Fwx_fmt%3Dgif%26from%3Dappmsg"/></span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">    然后就可以调用具体的</span></span><span lang="EN-US"><span leaf="">entry_point</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">了。</span></span></p><h1><span lang="EN-US"><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">3 Exception</span></span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">处理分析</span></span></span></h1><p style=""><span lang="EN-US"><span leaf="">    sptm</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">在启动阶段，将</span></span><span lang="EN-US"><span leaf="">syn_handler_sp0_g12</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">地址设置为</span></span><span lang="EN-US"><span leaf="">vbar_gl1</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">的异常处理地址。</span></span></p><p><span lang="EN-US" style="mso-no-proof:yes;"><span leaf=""><img data-aistatus="1" alt="1705977573086" class="rich_pages wxw-img" data-ratio="0.1265625" data-type="png" data-w="640" height="71" width="554" data-imgfileid="100000200" src="https://wechat2rss.xlab.app/img-proxy/?k=0e24a9e0&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_gif%2F4iaJia7Cvd3PCeibxXOIGLRw6XZ7fY9oXHBBTFuhwgsOJgB7vSZLKZMUXR4YFiaxreYU7044voFdWyLWsQcAMXoV1Q%2F640%3Fwx_fmt%3Dgif%26from%3Dappmsg"/></span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">    以</span></span><span lang="EN-US"><span leaf="">syn_handler_sp0_g12+0x400</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">的异常处理函数为例，追踪</span></span><span lang="EN-US"><span leaf="">sptm</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">如何处理来自</span></span><span lang="EN-US"><span leaf="">gl0</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">的异常，逻辑还原如下：</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf=""><span class="code-snippet__built_in">syn_handler_low_gl2</span>(<span class="code-snippet__type">uint64_t</span> event_metadata)</span></code><br/><code><span leaf="">{</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> ec_value = (<span class="code-snippet__built_in">msr</span>(ESR_GL1) &gt;&gt; <span class="code-snippet__number">26</span>) &amp; <span class="code-snippet__number">3</span>f;</span></code><br/><code><span leaf="">   <span class="code-snippet__type">uint64_t</span> svc_number = <span class="code-snippet__built_in">msr</span>(ESR_GL1) &amp; <span class="code-snippet__number">0xffff</span>;</span></code><br/><code><span leaf="">   <span class="code-snippet__keyword">if</span> (ec_value == <span class="code-snippet__number">0x15</span>) {</span></code><br/><code><span leaf="">     <span class="code-snippet__keyword">if</span> (svc_number == <span class="code-snippet__number">0</span>) {</span></code><br/><code><span leaf="">       <span class="code-snippet__type">uint64_t</span> value = (event_metadata &gt;&gt; <span class="code-snippet__number">32</span>) &amp; <span class="code-snippet__number">0xffff</span>;</span></code><br/><code><span leaf="">       <span class="code-snippet__keyword">if</span> (value != <span class="code-snippet__number">0xfd</span>) {</span></code><br/><code><span leaf="">         <span class="code-snippet__keyword">if</span> (value != <span class="code-snippet__number">0xfe</span>) {</span></code><br/><code><span leaf="">           <span class="code-snippet__keyword">if</span> (value != <span class="code-snippet__number">0xff</span>) {</span></code><br/><code><span leaf="">             <span class="code-snippet__built_in">dispatch_state_machine</span>(<span class="code-snippet__number">2</span>, event_metadata);</span></code><br/><code><span leaf="">           }</span></code><br/><code><span leaf="">           <span class="code-snippet__keyword">else</span> {</span></code><br/><code><span leaf="">             <span class="code-snippet__built_in">dispatch_state_machine</span>(<span class="code-snippet__number">7</span>, <span class="code-snippet__number">1</span>);</span></code><br/><code><span leaf="">           }</span></code><br/><code><span leaf="">         }</span></code><br/><code><span leaf="">         <span class="code-snippet__keyword">else</span> {</span></code><br/><code><span leaf="">           <span class="code-snippet__built_in">dispatch_state_machine</span>(<span class="code-snippet__number">0xb</span>, <span class="code-snippet__number">0</span>);</span></code><br/><code><span leaf="">         }</span></code><br/><code><span leaf="">        }</span></code><br/><code><span leaf="">       <span class="code-snippet__keyword">else</span> {</span></code><br/><code><span leaf="">         <span class="code-snippet__built_in">dispatch_state_machine</span>(<span class="code-snippet__number">5</span>, <span class="code-snippet__number">0</span>);</span></code><br/><code><span leaf="">       }</span></code><br/><code><span leaf="">     }</span></code><br/><code><span leaf="">     <span class="code-snippet__keyword">else</span> <span class="code-snippet__keyword">if</span> (svc_number == <span class="code-snippet__number">37</span>) {</span></code><br/><code><span leaf="">        <span class="code-snippet__type">uint64_t</span> value = <span class="code-snippet__built_in">mrs</span>(SPSR_GL1);</span></code><br/><code><span leaf="">       <span class="code-snippet__built_in">msr</span>(value &amp; ~<span class="code-snippet__number">0x1C0</span>);</span></code><br/><code><span leaf="">     }</span></code><br/><code><span leaf="">     <span class="code-snippet__keyword">else</span> <span class="code-snippet__keyword">if</span> (svc_number == <span class="code-snippet__number">38</span>) {</span></code><br/><code><span leaf="">        <span class="code-snippet__type">uint64_t</span> value = <span class="code-snippet__built_in">mrs</span>(SPSR_GL1);</span></code><br/><code><span leaf="">        <span class="code-snippet__built_in">msr</span>(value | <span class="code-snippet__number">0x1C0</span>);</span></code><br/><code><span leaf="">      }</span></code><br/><code><span leaf="">     <span class="code-snippet__keyword">else</span> {</span></code><br/><code><span leaf="">       <span class="code-snippet__built_in">dead_loop</span>();</span></code><br/><code><span leaf="">     }</span></code><br/><code><span leaf="">   }</span></code><br/><code><span leaf="">   <span class="code-snippet__keyword">else</span> <span class="code-snippet__keyword">if</span> (ec_value == <span class="code-snippet__number">0x16</span>) {</span></code><br/><code><span leaf="">   }</span></code><br/><code><span leaf="">   <span class="code-snippet__keyword">else</span> {</span></code><br/><code><span leaf="">     <span class="code-snippet__built_in">handle_unkdown_exception_gl12</span>();</span></code><br/><code><span leaf="">   }</span></code><br/><code><span leaf="">}</span></code><br/></pre></p><p style=""><span lang="EN-US"><span leaf="">    syn_handler_low_gl2</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">提供了</span></span><span lang="EN-US"><span leaf="">3</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">个系统调用：</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="apache"><code><span leaf=""><span class="code-snippet__attribute">Svc</span> <span class="code-snippet__number">0</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">Svc</span> <span class="code-snippet__number">37</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">Svc</span> <span class="code-snippet__number">38</span></span></code><br/></pre></p><p style="mso-pagination:widow-orphan;"><span lang="EN-US"><span leaf="">    后两个系统调用用于关闭中断。</span></span></p><p style=""><span lang="EN-US"><span leaf="">Svc 0</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">有如下触发路径：</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="apache"><code><span leaf=""><span class="code-snippet__attribute">dispatch_state_machine</span>(<span class="code-snippet__number">2</span>, event_metadata);</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">dispatch_state_machine</span>(<span class="code-snippet__number">7</span>, <span class="code-snippet__number">1</span>);</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">dispatch_state_machine</span>(<span class="code-snippet__number">0</span>xb, <span class="code-snippet__number">0</span>);</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">dispatch_state_machine</span>(<span class="code-snippet__number">5</span>, <span class="code-snippet__number">0</span>);</span></code><br/></pre></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">    同时可以看到，异常处理中并没有对关键寄存器进行保护。</span></span></p><h1><span lang="EN-US"><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">4 sptm</span></span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">页表保护</span></span></span></h1><p style=""><span lang="EN-US"><span leaf="">    sptm</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">是</span></span><span lang="EN-US"><span leaf="">secure page table monitor</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">的缩写，</span></span><span lang="EN-US"><span leaf="">ios</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">将原本</span></span><span lang="EN-US"><span leaf="">xnu</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">内核中的页表映射代码转移到了</span></span><span lang="EN-US"><span leaf="">sptm</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，也就是</span></span><span lang="EN-US"><span leaf="">gl2</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">模式进行处理。</span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">    页表映射的函数原型：</span></span><span lang="EN-US"><span leaf="">sptm_map_page(uint64_t paddr, uint64_t vaddr, uint64_t new_pte)</span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">    首先调用</span></span><span lang="EN-US"><span leaf="">acquire_root_pt</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">获取</span></span><span lang="EN-US"><span leaf="">root</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">页目录表的地址。</span></span></p><p style=""><span lang="EN-US" style="mso-no-proof:yes;"><span leaf=""><img data-aistatus="1" alt="1705979708388" class="rich_pages wxw-img" data-ratio="0.428125" data-type="png" data-w="640" height="207" width="482" data-imgfileid="100000205" src="https://wechat2rss.xlab.app/img-proxy/?k=57634df5&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_gif%2F4iaJia7Cvd3PCeibxXOIGLRw6XZ7fY9oXHBekHX94D12M4pNjJl1ZNcUc9DNgc7fW97KfXB4Mydpq9WkphPM6VT2w%2F640%3Fwx_fmt%3Dgif%26from%3Dappmsg"/></span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">    接着调用</span></span><span lang="EN-US"><span leaf="">check_vaddr_range</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">检查虚拟地址</span></span><span lang="EN-US"><span leaf="">vaddr</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">是否在</span></span><span lang="EN-US"><span leaf="">root</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">页目标表所能翻译的地址范围内，注意每层目录表都有一个能翻译的地址范围。</span></span></p><p style=""><span lang="EN-US" style="mso-no-proof:yes;"><span leaf=""><img data-aistatus="1" alt="1705979782003(1)" class="rich_pages wxw-img" data-ratio="0.1578125" data-type="png" data-w="640" height="71" width="449" data-imgfileid="100000203" src="https://wechat2rss.xlab.app/img-proxy/?k=5db15e52&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_gif%2F4iaJia7Cvd3PCeibxXOIGLRw6XZ7fY9oXHBma2MtVhSZPyYyPh6UNnKrtHmibrUCFLBLiat0lbGUZSFy1myGaDXkC6w%2F640%3Fwx_fmt%3Dgif%26from%3Dappmsg"/></span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">    接着检查</span></span><span lang="EN-US"><span leaf="">new_pte</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">合法性。</span></span></p><p style=""><span lang="EN-US" style="mso-no-proof:yes;"><span leaf=""><img data-aistatus="1" alt="1705979898089(1)" class="rich_pages wxw-img" data-ratio="0.071875" data-type="png" data-w="640" height="34" width="462" data-imgfileid="100000202" src="https://wechat2rss.xlab.app/img-proxy/?k=9148e440&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_gif%2F4iaJia7Cvd3PCeibxXOIGLRw6XZ7fY9oXHBbicc0mF4JW4TMFWcrjOfA333xXTd3daibghUWDQctsRPdg8vPeibibyAicg%2F640%3Fwx_fmt%3Dgif%26from%3Dappmsg"/></span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">    然后通过</span></span><span lang="EN-US"><span leaf="">root_pt</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">对应的</span></span><span lang="EN-US"><span leaf="">attr_idx</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，在</span></span><span lang="EN-US"><span leaf="">attr_struct_array</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">中找到对应的结构体，判断物理地址</span></span><span lang="EN-US"><span leaf="">paddr</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">是否合法。</span></span></p><p style=""><span lang="EN-US" style="mso-no-proof:yes;"><span leaf=""><img data-aistatus="1" alt="1705979953206" class="rich_pages wxw-img" data-ratio="0.34375" data-type="png" data-w="640" height="190" width="553" data-imgfileid="100000204" src="https://wechat2rss.xlab.app/img-proxy/?k=88f7d077&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_gif%2F4iaJia7Cvd3PCeibxXOIGLRw6XZ7fY9oXHBMVNBQNddTMDcibia0ibhcN1dYibWRXB1rdVicx93vpe3xg7X6jonfJbRGDg%2F640%3Fwx_fmt%3Dgif%26from%3Dappmsg"/></span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">    接着获取中间目录表和最后的页表结构体。</span></span></p><p style=""><span lang="EN-US" style="mso-no-proof:yes;"><span leaf=""><img data-aistatus="1" alt="1705980083112" class="rich_pages wxw-img" data-ratio="0.89375" data-type="png" data-w="640" height="420" width="470" data-imgfileid="100000206" src="https://wechat2rss.xlab.app/img-proxy/?k=d647f7f9&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_gif%2F4iaJia7Cvd3PCeibxXOIGLRw6XZ7fY9oXHBgaWcm5iahxWDHSibqfvWyBU5MWgLsMicWacdr8AMTfeuKibESft7lV4GZw%2F640%3Fwx_fmt%3Dgif%26from%3Dappmsg"/></span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">    重点来了，</span></span><span lang="EN-US"><span leaf="">sptm_type_params_database</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">数组中隐藏着巨大秘密。</span></span></p><p style=""><span lang="EN-US" style="mso-no-proof:yes;"><span leaf=""><img data-aistatus="1" alt="1705981082105" class="rich_pages wxw-img" data-ratio="0.7703125" data-type="png" data-w="640" height="426" width="553" data-imgfileid="100000212" src="https://wechat2rss.xlab.app/img-proxy/?k=fbae93e3&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_gif%2F4iaJia7Cvd3PCeibxXOIGLRw6XZ7fY9oXHBX5sic3TYGsuVfYhj4Hj6bMfeicNkOtvMWvarcZRC4wKPP9lZ5t3ib2CgQ%2F640%3Fwx_fmt%3Dgif%26from%3Dappmsg"/></span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">首先通过页表</span></span><span lang="EN-US"><span leaf="">page_fte-&gt;type</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">在</span></span><span lang="EN-US"><span leaf="">sptm_type_params_database</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">数组中找到对应的</span></span><span lang="EN-US"><span leaf="">struct current_type_params</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">结构体，</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">它保存着此种类型页表对应的</span></span><span lang="EN-US"><span leaf="">sprr_index</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">，然后在</span></span><span lang="EN-US"><span leaf="">new_pte</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">中提取出新的页表对应的</span></span><span lang="EN-US"><span leaf="">sprr_index</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，将两者对比，如果不相等则中止此次页表映射。</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">也就是说</span></span><span lang="EN-US"><span leaf="">sptm</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">维护了一组</span></span><span lang="EN-US"><span leaf="">sprr_index</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">数据库，只有类型匹配才能有权限进行映射。</span></span></p><h1><span lang="EN-US"><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">5 sptm retype</span></span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">分类保护</span></span></span></h1><p style=""><span lang="EN-US"><span leaf="">Sptm</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">将不同的数据段或代码段进行分类保护，</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">每种不同的类型都有对应的地址范围，不同的类型不能互相映射，用分类概念完成了地址隔离保护。</span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">    在</span></span><span lang="EN-US"><span leaf="">sptm</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">启动阶段，调用</span></span><span lang="EN-US"><span leaf="">sptm_bootstrap_early</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">对若干地址区域进行了分类注册：</span></span></p><p style=""><span lang="EN-US" style="mso-no-proof:yes;"><span leaf=""><img data-aistatus="1" alt="1705991597946" class="rich_pages wxw-img" data-ratio="0.7296875" data-type="png" data-w="640" height="404" width="553" data-imgfileid="100000210" src="https://wechat2rss.xlab.app/img-proxy/?k=1792753c&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_gif%2F4iaJia7Cvd3PCeibxXOIGLRw6XZ7fY9oXHBWzZvlFxPfibO7CVw0T08b3lkRqPqKguOGINPgicGnhAYglecYnMlBobA%2F640%3Fwx_fmt%3Dgif%26from%3Dappmsg"/></span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">    对</span></span><span lang="EN-US"><span leaf="">papt_range_array</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">中的所有地址范围进行注册，</span></span><span lang="EN-US"><span leaf=""> retype</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">类型为</span></span><span lang="EN-US"><span leaf="">0x9</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。这些地址范围包括：</span></span><span lang="EN-US"><span leaf="">SPTM-rx</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">SPTM-rw</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">SPTM-le</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">TXM-ro</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">TXM-rx</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">TXM-bx</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">TXM-rw</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">BootKC-ro</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">BootKC-rs</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">BootKC-rx</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">BootKC-bx</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">BootKC-rw</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">BootKC-le</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">TrustCache</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">CL4-ro</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">CL4-rx</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">CL4-rw</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">CL4-le</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">RAMDisk</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">RTBuddySeg</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">SEPFW</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">SEPPatches</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">uStuff</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">preoslog</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">BootArgs</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">ExclaveOSIntegrityCatalog</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">ExclaveOSTrustCache</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">AVAILABLE</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">PHYS_SLIDE</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">等。</span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">    还有其他的地址范围注册了以下</span></span><span lang="EN-US"><span leaf="">retype</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">类型：</span></span><span lang="EN-US"><span leaf="">0xb</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">0x13</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">、</span></span><span lang="EN-US"><span leaf="">0x36</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">。</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="apache"><code><span leaf=""><span class="code-snippet__attribute">__text</span>:FFFFFFF0070866A8 MOV             X0, #<span class="code-snippet__number">0</span>xFFFFFFF000000000</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">__text</span>:FFFFFFF0070866AC MOV             W1, #<span class="code-snippet__number">1</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">__text</span>:FFFFFFF0070866B0 MOV             W2, #<span class="code-snippet__number">0</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">__text</span>:FFFFFFF0070866B4 MOV             W3, #<span class="code-snippet__number">0</span>x13</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">__text</span>:FFFFFFF0070866B8 MOV             W4, #<span class="code-snippet__number">3</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">__text</span>:FFFFFFF0070866BC MOV             W5, #<span class="code-snippet__number">1</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">__text</span>:FFFFFFF0070866C0 BL              retype_handler</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">retype_handler</span>(<span class="code-snippet__number">0</span>xFFFFFFF000000000,<span class="code-snippet__number">1</span>,<span class="code-snippet__number">0</span>,<span class="code-snippet__number">0</span>x13,<span class="code-snippet__number">3</span>,<span class="code-snippet__number">1</span>)</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">__text</span>:FFFFFFF0070866D8 ADD             X22, X22, #<span class="code-snippet__number">4</span>,LSL#<span class="code-snippet__number">12</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">__text</span>:FFFFFFF0070866DC MOV             X0, X22</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">__text</span>:FFFFFFF0070866E0 MOV             W1, #<span class="code-snippet__number">2</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">__text</span>:FFFFFFF0070866E4 MOV             W2, #<span class="code-snippet__number">0</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">__text</span>:FFFFFFF0070866E8 MOV             W3, #<span class="code-snippet__number">0</span>x13</span></code><br/><code><span leaf=""><span class="code-snippet__attribute">__text</span>:FFFFFFF0070866EC MOV             W4, #<span class="code-snippet__number">3</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">__text</span>:FFFFFFF0070866F0 MOV             W5, #<span class="code-snippet__number">1</span></span></code><br/><code><span leaf=""><span class="code-snippet__attribute">__text</span>:FFFFFFF0070866F4 BL              retype_handler</span></code><br/></pre></p><p style=""><span lang="EN-US"><span leaf="">retype_handler(x22,2,0,0x13,3,1)</span></span></p><p style=""><span lang="EN-US"><span leaf="">retype_handler</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">原型：</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf=""><span class="code-snippet__built_in">retype_handler</span>(<span class="code-snippet__type">uint64_t</span> base, <span class="code-snippet__type">uint64_t</span> length, x2, <span class="code-snippet__type">uint64_t</span> frame_type, <span class="code-snippet__type">uint64_t</span> max_num, <span class="code-snippet__type">bool</span> flag)；</span></code></pre></p><p style=""><span lang="EN-US" style="mso-no-proof:yes;"><span leaf=""><img data-aistatus="1" alt="1705993076335" class="rich_pages wxw-img" data-ratio="0.7015625" data-type="png" data-w="640" height="388" width="554" data-imgfileid="100000211" src="https://wechat2rss.xlab.app/img-proxy/?k=5831ec62&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_gif%2F4iaJia7Cvd3PCeibxXOIGLRw6XZ7fY9oXHBcgXBP9dCC6XLJ34diapzDb9GQUwy30e4hLibYQTtsDpszLAMBPNzUS0Q%2F640%3Fwx_fmt%3Dgif%26from%3Dappmsg"/></span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">    首先根据参数</span></span><span lang="EN-US"><span leaf="">base</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">在</span></span><span lang="EN-US"><span leaf="">retype_range_array</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">数组中找到其对应的</span></span><span lang="EN-US"><span leaf="">retype_array</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">数组地址。</span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">    接着调用</span></span><span lang="EN-US"><span leaf="">bootstrap_alloc_frames</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">分配一个</span></span><span lang="EN-US"><span leaf="">retype</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">帧结构体。</span></span></p><p style=""><span lang="EN-US" style="mso-no-proof:yes;"><span leaf=""><img data-aistatus="1" alt="1705993329299" class="rich_pages wxw-img" data-ratio="0.075" data-type="png" data-w="640" height="42" width="554" data-imgfileid="100000208" src="https://wechat2rss.xlab.app/img-proxy/?k=e04b26cc&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_gif%2F4iaJia7Cvd3PCeibxXOIGLRw6XZ7fY9oXHB3dFqtLiccpCGJ8Bzqxx1xjibAu4MJ2PTGI1j22fGw08tDNcwkhkHxIbg%2F640%3Fwx_fmt%3Dgif%26from%3Dappmsg"/></span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">然后调用</span></span><span lang="EN-US"><span leaf="">bootstrap_retype_frames</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">将刚分配到的</span></span><span lang="EN-US"><span leaf="">retype</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">帧结构进行下一步操作。</span></span></p><p style=""><span lang="EN-US" style="mso-no-proof:yes;"><span leaf=""><img data-aistatus="1" alt="1705993438713" class="rich_pages wxw-img" data-ratio="0.134375" data-type="png" data-w="640" height="75" width="553" data-imgfileid="100000209" src="https://wechat2rss.xlab.app/img-proxy/?k=29ddd145&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_gif%2F4iaJia7Cvd3PCeibxXOIGLRw6XZ7fY9oXHBcwa0QLjd8oEdbUNgGR1OMGtSzA4ppF6cByZLF49e39KZMZZ7x2PiaSQ%2F640%3Fwx_fmt%3Dgif%26from%3Dappmsg"/></span></span></p><p style=""><span lang="EN-US"><span leaf="">bootstrap_retype_frames</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">函数原型：</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf=""><span class="code-snippet__built_in">bootstrap_retype_frames</span>(<span class="code-snippet__type">uint64_t</span> frame_start_address, <span class="code-snippet__type">uint64_t</span> frame_num, <span class="code-snippet__type">uint64_t</span> old_type, <span class="code-snippet__type">uint64_t</span> new_type)；</span></code></pre></p><p style=""><span lang="EN-US"><span leaf="">    bootstrap_retype_frames</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">调用</span></span><span lang="EN-US"><span leaf="">set_retype_by_sprr</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">完成类型编码的存储操作。</span></span></p><p style=""><span lang="EN-US"><span leaf="">    set_retype_by_sprr</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">原型：</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><code><span leaf=""><span class="code-snippet__built_in">set_retype_by_sprr</span>(<span class="code-snippet__type">uint64_t</span> *retype_address, <span class="code-snippet__type">uint64_t</span> sprr_index)</span></code></pre></p><p style=""><span lang="EN-US" style="mso-no-proof:yes;"><span leaf=""><img data-aistatus="1" alt="1705994270713" class="rich_pages wxw-img" data-ratio="0.5640625" data-type="png" data-w="640" height="313" width="554" data-imgfileid="100000213" src="https://wechat2rss.xlab.app/img-proxy/?k=16f77b82&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_gif%2F4iaJia7Cvd3PCeibxXOIGLRw6XZ7fY9oXHBmvIYjVDhfoDFQcbO3MpuOic0Gsnhgwvd9nFUZQqsEo2AGXqjt0n4ibkA%2F640%3Fwx_fmt%3Dgif%26from%3Dappmsg"/></span></span></p><p style=""><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">    最终看到是将</span></span><span lang="EN-US"><span leaf="">sprr_index</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">编码进了</span></span><span lang="EN-US"><span leaf="">retype_array</span></span><span style="font-family:宋体;mso-ascii-font-family:
Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">数组。</span></span></p><h1><span lang="EN-US"><span leaf=""><span textstyle="" style="font-weight: bold;font-style: italic;">6 txm</span></span></span></h1><p style=""><span lang="EN-US"><span leaf="">txm</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">为</span></span><span lang="EN-US"><span leaf="">trust execution monitor</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:
minor-latin;"><span leaf="">的缩写，运行在</span></span><span lang="EN-US"><span leaf="">gl0</span></span><span style="font-family:
宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">，通过</span></span><span lang="EN-US"><span leaf="">svc</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">请求</span></span><span lang="EN-US"><span leaf="">sptm</span></span><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;"><span leaf="">服务：</span></span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="makefile"><code><span leaf=""><span class="code-snippet__section">__bootcode:FFFFFFF017054084 loc_FFFFFFF017054084 ; CODE XREF: sub_FFFFFFF017021C44+291BC↑j</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__bootcode:FFFFFFF017054084 ; sub_FFFFFFF01704AE04+10↑j ...</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__bootcode:FFFFFFF017054084 PACIBSP</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__bootcode:FFFFFFF017054088 SVC             0</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__bootcode:FFFFFFF01705408C RETAB</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__bootcode:FFFFFFF01705408C ; END OF FUNCTION CHUNK FOR sub_FFFFFFF017021C44</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__bootcode:FFFFFFF017054090 sub_FFFFFFF017054090 ; CODE XREF: start+48↑p</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__bootcode:FFFFFFF017054090</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__bootcode:FFFFFFF017054090 ; FUNCTION CHUNK AT __bootcode:FFFFFFF017054084 SIZE 0000000C BYTES</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__bootcode:FFFFFFF017054090</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__bootcode:FFFFFFF017054090 MOVK            X16, #0,LSL#48</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__bootcode:FFFFFFF017054094 MOVK            X16, #1,LSL#32</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__bootcode:FFFFFFF017054098 MOVK            X16, #0,LSL#16</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__bootcode:FFFFFFF01705409C MOVK            X16, #1</span></span></code><br/><code><span leaf=""><span class="code-snippet__section">__bootcode:FFFFFFF0170540A0 B               loc_FFFFFFF017054084</span></span></code><br/></pre></p><p style="display: none;"><mp-style-type data-value="3"></mp-style-type></p>


<p><a href="%27%27">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=b5b82e28&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg4NjU1NDU4MA%3D%3D%26mid%3D2247483864%26idx%3D1%26sn%3D399ce7d4205f1273e9834467678e5b6d">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Fri, 02 Jan 2026 17:57:00 +0800</pubDate>
    </item>
    <item>
      <title>苹果Webkit安全机制分析</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg4NjU1NDU4MA==&amp;mid=2247483834&amp;idx=1&amp;sn=144af0c9a52a75f37834238ae0875bce</link>
      <description></description>
      <content:encoded><![CDATA[<p>
原创 <span>wzt</span> <span>2024-03-13 20:58</span> <span style="display: inline-block;">上海</span>
</p>

<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=a79cb819&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_jpg%2F4iaJia7Cvd3PAdGIVfY8GSJW730JBFkrv8rUibGtIFfibjZEDlTw266cN4QGZJYOmXcSZjw4ibX8YLNWdmxsVPWxNvQ%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  本文详细分析了苹果</span><span style="font-family:Calibri;">Webkit</span><span style="font-family:宋体;">使用到的</span><span style="font-family:Calibri;">6</span><span style="font-family:宋体;">个安全功能：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="diff"><code><span class="code-snippet_outer"><span class="code-snippet__deletion">- Jit write protection</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__deletion">- Jit pac</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__deletion">- Gigacage</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__deletion">- JitCage</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__deletion">- Isolate Heap</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__deletion">- StructureID Protection</span></span></code></pre></section><h1><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;"><span style="font-family:Calibri;">1 JIT WRITE Protection</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;"><o:p></o:p></span></strong></h1><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    Webkit</span><span style="font-family:宋体;">中的</span><span style="font-family:Calibri;">JavaScriptCore(JSC)</span><span style="font-family:宋体;">引擎在使用</span><span style="font-family:Calibri;">JIT</span><span style="font-family:宋体;">技术时，将</span><span style="font-family:Calibri;">jit</span><span style="font-family:宋体;">存放的内存做了写和执行权限分离的保护，用到了两个技术：</span><span style="font-family:Calibri;">APRR</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">Separated WX Heap</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h2 style="margin-left:0.0000pt;text-indent:0.0000pt;mso-list:l0 level2 lfo1;"><span style="font-family:Arial;mso-fareast-font-family:黑体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;">1.1 </span><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">APRR</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    Apple</span><span style="font-family:宋体;">自研芯片新增了一个快速权限映射机制</span><span style="font-family:Calibri;">APRR</span><span style="font-family:宋体;">，它将</span><span style="font-family:Calibri;">arm</span><span style="font-family:宋体;">公版中的页表中原本的</span><span style="font-family:Calibri;">8</span><span style="font-family:宋体;">个权限组合扩展为了</span><span style="font-family:Calibri;">16</span><span style="font-family:宋体;">个，并提供了一些列新的寄存器来配合这个机制，可以让应用程序不用使用</span><span style="font-family:Calibri;">Mmap/mprotect</span><span style="font-family:宋体;">系统调用，就能设置页表的权限，不仅提高了访问页表的速度，还能将一个页表设置为只执行权限，这使得基于这一技术的</span><span style="font-family:Calibri;">webkit</span><span style="font-family:宋体;">从性能和安全都得到了极大的提升。关于</span><span style="font-family:Calibri;">APRR</span><span style="font-family:宋体;">可以参考博主</span><span style="font-family:Calibri;">ios</span><span style="font-family:宋体;">系列中关于</span><span style="font-family:Calibri;">PPL</span><span style="font-family:宋体;">技术的分析。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  苹果公司将</span><span style="font-family:Calibri;">APRR</span><span style="font-family:宋体;">做了一些封装提供给</span><span style="font-family:Calibri;">app</span><span style="font-family:宋体;">使用，</span><span style="font-family:Calibri;">JSC</span><span style="font-family:宋体;">在初始化中会有如下的一些调用：</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer">JavaScriptCore/jit/ExecutableAllocator.cpp</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> OS(DARWIN) &amp;&amp; CPU(ARM64)</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> USE(PTHREAD_JIT_PERMISSIONS_API)</span></span></code><code><span class="code-snippet_outer">        fastJITPermissionsIsSupported = !!pthread_jit_write_protect_supported_np();</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">elif</span> USE(APPLE_INTERNAL_SDK)</span></span></code><code><span class="code-snippet_outer">        fastJITPermissionsIsSupported = !!os_thread_self_restrict_rwx_is_supported();</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  苹果公司在</span><span style="font-family:Calibri;">pthread</span><span style="font-family:宋体;">中提供封装了对</span><span style="font-family:Calibri;">jit</span><span style="font-family:宋体;">操作的一些辅助函数，</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;background:rgb(255,255,0);mso-highlight:rgb(255,255,0);">pthread_jit_write_protect_</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;background:rgb(255,255,0);mso-highlight:rgb(255,255,0);"><span style="font-family:Calibri;">*</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">系列函数最终会通过</span><span style="font-family:Calibri;">msr</span><span style="font-family:宋体;">指令调用</span><span style="font-family:Calibri;">aprr</span><span style="font-family:宋体;">机制。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  系统在启动时会自动将每个进程的每个线程内存设置为不可写只执行状态，注意是每个线程都能独立的设置只执行权限，</span> <span style="font-family:宋体;">如果一个线程与另一个线程共享一块内存，其中一个线程打开了写权限，对另一个线程来讲仍然是只执行的。对于</span><span style="font-family:Calibri;">JIT</span><span style="font-family:宋体;">来讲，需要先调用</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">pthread_jit_write_protect_np</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">(false)</span><span style="font-family:宋体;">关闭只执行，打开写权限，写入</span><span style="font-family:Calibri;">JIT code</span><span style="font-family:宋体;">后，在调用</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">pthread_jit_write_protect_np</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">(true)</span><span style="font-family:宋体;">恢复执行权限。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;"> 我们看下</span><span style="font-family:Calibri;">libpthread</span><span style="font-family:宋体;">的相关代码：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">void</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">pthread_jit_write_protect_np</span><span class="code-snippet__params">(<span class="code-snippet__keyword">int</span> enable)</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">if</span> (!os_thread_self_restrict_rwx_is_supported()) {</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">return</span>;</span></code><code><span class="code-snippet_outer">  }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">if</span> (enable) {</span></code><code><span class="code-snippet_outer">    os_thread_self_restrict_rwx_to_rx();</span></code><code><span class="code-snippet_outer">  } <span class="code-snippet__keyword">else</span> {</span></code><code><span class="code-snippet_outer">    os_thread_self_restrict_rwx_to_rw();</span></code><code><span class="code-snippet_outer">  }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> _PTHREAD_CONFIG_JIT_WRITE_PROTECT</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__comment">// Validate _after_ toggling.</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">union</span> _pthread_jit_config_u *config = &amp;_pthread_jit_config;</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">if</span> (config-&gt;allowlist_enabled) {</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span> (!enable) {</span></code><code><span class="code-snippet_outer">      os_thread_self_restrict_rwx_to_rx();</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    PTHREAD_CLIENT_CRASH(<span class="code-snippet__number">0</span>,</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__string">&#34;pthread_jit_write_protect_np() disallowed by allowlist&#34;</span>);</span></code><code><span class="code-snippet_outer">  }</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span> <span class="code-snippet__comment">// _PTHREAD_CONFIG_JIT_WRITE_PROTECT</span></span></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  实际上还是使用了</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;background:rgb(255,255,0);mso-highlight:rgb(255,255,0);">os_thread_self_restrict_rwx_to_rx</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">系统库提供的</span><span style="font-family:Calibri;">c</span><span style="font-family:宋体;">接口。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  可以看到使用</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">pthread_jit_write_protect_np</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">接口可以关闭只执行内存，会带来一些安全问题，苹果的做法是增加了一些</span><span style="font-family:Calibri;">entitlement</span><span style="font-family:宋体;">，只对特定的</span><span style="font-family:Calibri;">app</span><span style="font-family:宋体;">进行授权。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">com</span><span class="code-snippet__selector-class">.apple</span><span class="code-snippet__selector-class">.security</span><span class="code-snippet__selector-class">.cs</span><span class="code-snippet__selector-class">.allow-jit</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">com</span><span class="code-snippet__selector-class">.apple</span><span class="code-snippet__selector-class">.security</span><span class="code-snippet__selector-class">.cs</span><span class="code-snippet__selector-class">.jit-write-allowlist</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">com</span><span class="code-snippet__selector-class">.apple</span><span class="code-snippet__selector-class">.security</span><span class="code-snippet__selector-class">.cs</span><span class="code-snippet__selector-class">.jit-write-allowlist-freeze-late</span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  请参考：</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p><span style="text-decoration:underline;"><span style="font-family: 宋体;color: rgb(0, 0, 255);font-size: 12pt;">Porting Just-In-Time Compilers to Apple Silicon | Apple Developer Documentation</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;font-size:12.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p><span style="text-decoration:underline;"><span style="font-family: 宋体;color: rgb(0, 0, 255);font-size: 12pt;">PTHREAD_JIT_WRITE_PROTECT_NP(3) (keith.github.io)</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;font-size:12.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p><span style="text-decoration:underline;"><span style="font-family: 宋体;color: rgb(0, 0, 255);font-size: 12pt;">pthread.c (apple.com)</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;font-size:12.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h2 style="margin-left:0.0000pt;text-indent:0.0000pt;mso-list:l0 level2 lfo1;"><span style="font-family:Arial;mso-fareast-font-family:黑体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;">1.2 </span><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">Separated WX Heap</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  当硬件不支持</span><span style="font-family:Calibri;">APRR</span><span style="font-family:宋体;">时， </span><span style="font-family:Calibri;">JSC</span><span style="font-family:宋体;">使用了一种叫做</span><span style="font-family:Calibri;">Separated wx heap</span><span style="font-family:宋体;">的技术，首先我们得看下</span><span style="font-family:Calibri;">JSC</span><span style="font-family:宋体;">是如何初始化</span><span style="font-family:Calibri;">JIT</span><span style="font-family:宋体;">用到的内存的：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="php"><code><span class="code-snippet_outer">computeCanUseJIT-&gt;canUseAssembler-&gt;enableAssembler-&gt;ExecutableAllocator::initializeUnderlyingAllocator-&gt;initializeJITPageReservation</span></code><code><span class="code-snippet_outer">JavaScriptCore/jit/ExecutableAllocator.cpp：</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">static</span> ALWAYS_INLINE JITReservation initializeJITPageReservation()</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">reservation.size = fixedExecutableMemoryPoolSize;</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  首先设置</span><span style="font-family:Calibri;">jit</span><span style="font-family:宋体;">的内存大小，对于</span><span style="font-family:Calibri;">arm64</span><span style="font-family:宋体;">默认使用</span><span style="font-family:Calibri;">128M</span><span style="font-family:宋体;">内存，因为</span><span style="font-family:Calibri;">arm Near jump</span><span style="font-family:宋体;">指令最大的寻址范围即为</span><span style="font-family:Calibri;">128M</span><span style="font-family:宋体;">，但是</span><span style="font-family:Calibri;">JSC</span><span style="font-family:宋体;">还使用了一种叫做</span><span style="font-family:Calibri;">ISLAND</span><span style="font-family:宋体;">的技术，可以寻址</span><span style="font-family:Calibri;">512M</span><span style="font-family:宋体;">内存，这个后续在展开讲。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="php"><code><span class="code-snippet_outer">    auto tryCreatePageReservation = [] (size_t reservationSize) {</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (Options::useJITCage() &amp;&amp; JSC_ALLOW_JIT_CAGE_SPECIFIC_RESERVATION)</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">return</span> PageReservation::tryReserve(reservationSize, OSAllocator::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, <span class="code-snippet__keyword">true</span>, Options::useJITCage());</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> PageReservation::tryReserveWithGuardPages(reservationSize, OSAllocator::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, <span class="code-snippet__keyword">true</span>, <span class="code-snippet__keyword">false</span>);</span></code><code><span class="code-snippet_outer">    };</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">reservation.pageReservation = tryCreatePageReservation(reservation.size);</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  调用</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">PageReservation::tryReserve</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">进一步调用</span><span style="font-family:Calibri;">OSAllocator::tryReserveUncommitted</span><span style="font-family:宋体;">，而后调用</span><span style="font-family:Calibri;">mmap</span><span style="font-family:宋体;">传递</span><span style="font-family:Calibri;">MAP_JIT</span><span style="font-family:宋体;">参数分配内存。</span><span style="font-family:Calibri;">MAP_JIT</span><span style="font-family:宋体;">是苹果公司给</span><span style="font-family:Calibri;">mmap</span><span style="font-family:宋体;">系统调用新增的一个参数，用来服务</span><span style="font-family:Calibri;">JIT</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">xnu-xnu-8020</span><span class="code-snippet__selector-class">.140</span><span class="code-snippet__selector-class">.41</span>\<span class="code-snippet__selector-tag">bsd</span>\<span class="code-snippet__selector-tag">sys</span>\<span class="code-snippet__selector-tag">mman</span><span class="code-snippet__selector-class">.h</span>:</span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-id">#define</span> <span class="code-snippet__selector-tag">MAP_JIT</span>          0<span class="code-snippet__selector-tag">x0800</span> <span class="code-snippet__comment">/* Allocate a region that will be used for JIT purposes */</span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  对于</span><span style="font-family:Calibri;">JIT</span><span style="font-family:宋体;">内存，</span><span style="font-family:Calibri;">xnu</span><span style="font-family:宋体;">内核限制住每个进程仅有一块内存用来存放</span><span style="font-family:Calibri;">JIT</span><span style="font-family:宋体;">代码。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">Osfmk\vm\vm_map.<span class="code-snippet__function">c</span></span></code><code><span class="code-snippet_outer">kern_return_t</span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">vm_map_locate_space</span><span class="code-snippet__params">(</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">vm_map_t</span>                <span class="code-snippet__built_in">map</span>,</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">vm_map_size_t</span>           size,</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">vm_map_offset_t</span>         mask,</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">vm_map_kernel_flags_t</span>   vmk_flags,</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">vm_map_offset_t</span>        *start_inout,</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">vm_map_entry_t</span>         *entry_out)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span> (vmk_flags.vmkf_map_jit) {</span></code><code><span class="code-snippet_outer">      <span class="code-snippet__keyword">if</span> (<span class="code-snippet__built_in">map</span>-&gt;jit_entry_exists &amp;&amp;</span></code><code><span class="code-snippet_outer">          !VM_MAP_POLICY_ALLOW_MULTIPLE_JIT(<span class="code-snippet__built_in">map</span>)) {</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> KERN_INVALID_ARGUMENT;</span></code><code><span class="code-snippet_outer">      }</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  回到</span><span style="font-family:Calibri;">initializeJITPageReservation</span><span style="font-family:宋体;">：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> ENABLE(SEPARATED_WX_HEAP)</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (!g_jscConfig.useFastJITPermissions) {</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__comment">// First page of our JIT allocation is reserved.</span></span></code><code><span class="code-snippet_outer">            ASSERT(reservation.size &gt;= executablePageSize() * <span class="code-snippet__number">2</span>);</span></code><code><span class="code-snippet_outer">            reservation.<span class="code-snippet__keyword">base</span> = (<span class="code-snippet__keyword">void</span>*)((uintptr_t)(reservation.<span class="code-snippet__keyword">base</span>) + executablePageSize());</span></code><code><span class="code-snippet_outer">            reservation.size -= executablePageSize();</span></code><code><span class="code-snippet_outer">            initializeSeparatedWXHeaps(reservation.pageReservation.<span class="code-snippet__keyword">base</span>(), executablePageSize(), reservation.<span class="code-snippet__keyword">base</span>, reservation.size);</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  如果不支持</span><span style="font-family:Calibri;">APRR</span><span style="font-family:宋体;">，就调用</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">initializeSeparatedWXHeaps</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">初始化刚申请过的</span><span style="font-family:Calibri;">JIT</span><span style="font-family:宋体;">内存。在这之前</span><span style="font-family:Calibri;">JIT</span><span style="font-family:宋体;">内存最开始的一个</span><span style="font-family:Calibri;">PAGE</span><span style="font-family:宋体;">保留，后面设置为只执行权限。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">static</span> ALWAYS_INLINE <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">initializeSeparatedWXHeaps</span><span class="code-snippet__params">(<span class="code-snippet__keyword">void</span>* stubBase, <span class="code-snippet__keyword">size_t</span> stubSize, <span class="code-snippet__keyword">void</span>* jitBase, <span class="code-snippet__keyword">size_t</span> jitSize)</span></span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">kern_return_t</span> ret = mach_vm_remap(mach_task_self(), &amp;writableAddr, jitSize, <span class="code-snippet__number">0</span>,</span></code><code><span class="code-snippet_outer">        remapFlags,</span></code><code><span class="code-snippet_outer">        mach_task_self(), (<span class="code-snippet__keyword">mach_vm_address_t</span>)jitBase, FALSE,</span></code><code><span class="code-snippet_outer">        &amp;cur, &amp;max, VM_INHERIT_DEFAULT);</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  使用</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">mach_vm_remap</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">函数将</span><span style="font-family:Calibri;">jit</span><span style="font-family:宋体;">内存重映射到一块新的内存中，地址由</span><span style="font-family:Calibri;">writeableAddr</span><span style="font-family:宋体;">指向，注意原来的</span><span style="font-family:Calibri;">jit</span><span style="font-family:宋体;">内存仍旧是保留的，这样就会有两块虚拟内存指向了同一块物理内存。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">MacroAssemblerCodeRef&lt;JITThunkPtrTag&gt; writeThunk = jitWriteThunkGenerator(<span class="code-snippet__keyword">reinterpret_cast</span>&lt;<span class="code-snippet__keyword">void</span>*&gt;(writableAddr), stubBase, stubSize);</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  调用</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">jitWriteThunkGenerator</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">函数用来设置一个优化过的</span><span style="font-family:Calibri;">memcpy</span><span style="font-family:宋体;">函数：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">static</span> ALWAYS_INLINE MacroAssemblerCodeRef&lt;JITThunkPtrTag&gt; jitWriteThunkGenerator(<span class="code-snippet__keyword">void</span>* writableAddr, <span class="code-snippet__keyword">void</span>* stubBase, <span class="code-snippet__keyword">size_t</span> stubSize)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">    MacroAssembler jit;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    jit.tagReturnAddress();</span></code><code><span class="code-snippet_outer">    jit.move(MacroAssembler::TrustedImmPtr(writableAddr), x7);</span></code><code><span class="code-snippet_outer">    jit.addPtr(x7, x0);</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  这段</span><span style="font-family:Calibri;">jit code</span><span style="font-family:宋体;">是把</span><span style="font-family:Calibri;">writableAddr</span><span style="font-family:宋体;">传递给</span><span style="font-family:Calibri;">x7</span><span style="font-family:宋体;">寄存器，然后与</span><span style="font-family:Calibri;">x0</span><span style="font-family:宋体;">相加，这迫使</span><span style="font-family:Calibri;">memcpy</span><span style="font-family:宋体;">函数的目的地址始终在</span><span style="font-family:Calibri;">writableAddr</span><span style="font-family:宋体;">内存范围内。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="php"><code><span class="code-snippet_outer">    jit.move(x0, x3);</span></code><code><span class="code-snippet_outer">    MacroAssembler::Jump smallCopy = jit.branch64(MacroAssembler::Below, x2, MacroAssembler::TrustedImm64(<span class="code-snippet__number">64</span>));</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    jit.add64(TrustedImm32(<span class="code-snippet__number">32</span>), x3);</span></code><code><span class="code-snippet_outer">    jit.and64(TrustedImm32(<span class="code-snippet__number">-32</span>), x3);</span></code><code><span class="code-snippet_outer">    jit.loadPair64(x1, x12, x13);</span></code><code><span class="code-snippet_outer">    jit.loadPair64(x1, TrustedImm32(<span class="code-snippet__number">16</span>), x14, x15);</span></code><code><span class="code-snippet_outer">    jit.sub64(x3, x0, x5);</span></code><code><span class="code-snippet_outer">    jit.addPtr(x5, x1);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    jit.loadPair64(x1, x8, x9);</span></code><code><span class="code-snippet_outer">    jit.loadPair64(x1, TrustedImm32(<span class="code-snippet__number">16</span>), x10, x11);</span></code><code><span class="code-snippet_outer">    jit.add64(TrustedImm32(<span class="code-snippet__number">32</span>), x1);</span></code><code><span class="code-snippet_outer">    jit.sub64(x5, x2);</span></code><code><span class="code-snippet_outer">    jit.storePair64(x12, x13, x0);</span></code><code><span class="code-snippet_outer">    jit.storePair64(x14, x15, x0, TrustedImm32(<span class="code-snippet__number">16</span>));</span></code><code><span class="code-snippet_outer">    MacroAssembler::Jump cleanup = jit.branchSub64(MacroAssembler::BelowOrEqual, TrustedImm32(<span class="code-snippet__number">64</span>), x2);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    MacroAssembler::Label copyLoop = jit.label();</span></code><code><span class="code-snippet_outer">    jit.storePair64WithNonTemporalAccess(x8, x9, x3);</span></code><code><span class="code-snippet_outer">    jit.storePair64WithNonTemporalAccess(x10, x11, x3, TrustedImm32(<span class="code-snippet__number">16</span>));</span></code><code><span class="code-snippet_outer">    jit.add64(TrustedImm32(<span class="code-snippet__number">32</span>), x3);</span></code><code><span class="code-snippet_outer">    jit.loadPair64WithNonTemporalAccess(x1, x8, x9);</span></code><code><span class="code-snippet_outer">    jit.loadPair64WithNonTemporalAccess(x1, TrustedImm32(<span class="code-snippet__number">16</span>), x10, x11);</span></code><code><span class="code-snippet_outer">    jit.add64(TrustedImm32(<span class="code-snippet__number">32</span>), x1);</span></code><code><span class="code-snippet_outer">    jit.branchSub64(MacroAssembler::Above, TrustedImm32(<span class="code-snippet__number">32</span>), x2).linkTo(copyLoop, &amp;jit);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    cleanup.link(&amp;jit);</span></code><code><span class="code-snippet_outer">    jit.add64(x2, x1);</span></code><code><span class="code-snippet_outer">    jit.loadPair64(x1, x12, x13);</span></code><code><span class="code-snippet_outer">    jit.loadPair64(x1, TrustedImm32(<span class="code-snippet__number">16</span>), x14, x15);</span></code><code><span class="code-snippet_outer">    jit.storePair64(x8, x9, x3);</span></code><code><span class="code-snippet_outer">    jit.storePair64(x10, x11, x3, TrustedImm32(<span class="code-snippet__number">16</span>));</span></code><code><span class="code-snippet_outer">    jit.addPtr(x2, x3);</span></code><code><span class="code-snippet_outer">    jit.storePair64(x12, x13, x3, TrustedImm32(<span class="code-snippet__number">32</span>));</span></code><code><span class="code-snippet_outer">    jit.storePair64(x14, x15, x3, TrustedImm32(<span class="code-snippet__number">48</span>));</span></code><code><span class="code-snippet_outer">    jit.ret();</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    MacroAssembler::Label local0 = jit.label();</span></code><code><span class="code-snippet_outer">    jit.load64(MacroAssembler::PostIndexAddress(x1, <span class="code-snippet__number">8</span>), x6);</span></code><code><span class="code-snippet_outer">    jit.store64(x6, MacroAssembler::PostIndexAddress(x3, <span class="code-snippet__number">8</span>));</span></code><code><span class="code-snippet_outer">    smallCopy.link(&amp;jit);</span></code><code><span class="code-snippet_outer">    jit.branchSub64(MacroAssembler::AboveOrEqual, TrustedImm32(<span class="code-snippet__number">8</span>), x2).linkTo(local0, &amp;jit);</span></code><code><span class="code-snippet_outer">MacroAssembler::Jump local2 = jit.branchAdd64(MacroAssembler::Equal, TrustedImm32(<span class="code-snippet__number">8</span>), x2);</span></code><code><span class="code-snippet_outer">    MacroAssembler::Label local1 = jit.label();</span></code><code><span class="code-snippet_outer">    jit.load8(x1, PostIndex(<span class="code-snippet__number">1</span>), x6);</span></code><code><span class="code-snippet_outer">    jit.store8(x6, x3, PostIndex(<span class="code-snippet__number">1</span>));</span></code><code><span class="code-snippet_outer">    jit.branchSub64(MacroAssembler::NotEqual, TrustedImm32(<span class="code-snippet__number">1</span>), x2).linkTo(local1, &amp;jit);</span></code><code><span class="code-snippet_outer">    local2.link(&amp;jit);</span></code><code><span class="code-snippet_outer">    jit.ret();</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  上面代码生成了</span><span style="font-family:Calibri;">memcpy</span><span style="font-family:宋体;">函数其他的代码。</span></span><span style="font-family: Calibri;font-size: 10.5pt;letter-spacing: 0.034em;"></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">auto</span> stubBaseCodePtr =   CodePtr&lt;LinkBufferPtrTag&gt;(tagCodePtr&lt;LinkBufferPtrTag&gt;(stubBase));</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function">LinkBuffer <span class="code-snippet__title">linkBuffer</span><span class="code-snippet__params">(jit, stubBaseCodePtr, stubSize, LinkBuffer::Profile::Thunk)</span></span>;</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  将这段</span><span style="font-family:Calibri;">jit code</span><span style="font-family:宋体;">链接到原始</span><span style="font-family:Calibri;">jit</span><span style="font-family:宋体;">内存中保留的第一个只执行</span><span style="font-family:Calibri;">PAGE</span><span style="font-family:宋体;">内存内。</span></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  回到</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">initializeSeparatedWXHeaps</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">：</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> USE(EXECUTE_ONLY_JIT_WRITE_FUNCTION)</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__comment">// Prevent reading the write thunk code.</span></span></code><code><span class="code-snippet_outer">    result = vm_protect(mach_task_self(), <span class="code-snippet__keyword">reinterpret_cast</span>&lt;<span class="code-snippet__keyword">vm_address_t</span>&gt;(stubBase), stubSize, <span class="code-snippet__literal">true</span>, VM_PROT_EXECUTE);</span></code><code><span class="code-snippet_outer">    RELEASE_ASSERT(!result);</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  对原始</span><span style="font-family:Calibri;">jit</span><span style="font-family:宋体;">内存的第一个</span><span style="font-family:Calibri;">PAGE</span><span style="font-family:宋体;">设置为只执行权限。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">    <span class="code-snippet__comment">// Prevent writing into the executable JIT mapping.</span></span></code><code><span class="code-snippet_outer">    result = vm_protect(mach_task_self(), <span class="code-snippet__keyword">reinterpret_cast</span>&lt;<span class="code-snippet__keyword">vm_address_t</span>&gt;(jitBase), jitSize, <span class="code-snippet__literal">true</span>, VM_PROT_READ | VM_PROT_EXECUTE);</span></code><code><span class="code-snippet_outer">RELEASE_ASSERT(!result);</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  对原始</span><span style="font-family:Calibri;">jit</span><span style="font-family:宋体;">只保留读和执行权限。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">    <span class="code-snippet__comment">// Prevent execution in the writable JIT mapping.</span></span></code><code><span class="code-snippet_outer">    result = vm_protect(mach_task_self(), <span class="code-snippet__keyword">static_cast</span>&lt;<span class="code-snippet__keyword">vm_address_t</span>&gt;(writableAddr), jitSize, <span class="code-snippet__literal">true</span>, VM_PROT_READ | VM_PROT_WRITE);</span></code><code><span class="code-snippet_outer">    RELEASE_ASSERT(!result);</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  对第二块</span><span style="font-family:Calibri;">jit</span><span style="font-family:宋体;">内存设置为读和写权限，当</span><span style="font-family:Calibri;">jit</span><span style="font-family:宋体;">要生成</span><span style="font-family:Calibri;">jit code</span><span style="font-family:宋体;">时会调用</span><span style="font-family:Calibri;">performJITMemcpy</span><span style="font-family:宋体;">将</span><span style="font-family:Calibri;">jit code</span><span style="font-family:宋体;">写入这个内存区域。而</span><span style="font-family:Calibri;">jit</span><span style="font-family:宋体;">返回给浏览器的那个</span><span style="font-family:Calibri;">jit</span><span style="font-family:宋体;">内存是原始的</span><span style="font-family:Calibri;">jit</span><span style="font-family:宋体;">只执行内存，这样攻击者实际就猜不出来可写的</span><span style="font-family:Calibri;">jit code</span><span style="font-family:宋体;">内存在哪，因为那块内存是随机化生成的，并没有暴露给浏览器。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  前面提到</span><span style="font-family:Calibri;">jit</span><span style="font-family:宋体;">内存默认设置为</span><span style="font-family:Calibri;">128M</span><span style="font-family:宋体;">，这是</span><span style="font-family:Calibri;">arm near jump</span><span style="font-family:宋体;">的最大范围，如何让</span><span style="font-family:Calibri;">jit</span><span style="font-family:宋体;">使用更多的内存，</span><span style="font-family:Calibri;">JSC</span><span style="font-family:宋体;">使用了一种叫做</span><span style="font-family:Calibri;">ISLAND</span><span style="font-family:宋体;">的技术，</span><span style="font-family:Calibri;">JSC</span><span style="font-family:宋体;">的注释中很清晰的表达了它的架构：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100000181" data-ratio="0.5416666666666666" data-s="300,640" style="" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=fa427a97&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_png%2F4iaJia7Cvd3PAdGIVfY8GSJW730JBFkrv8lCv7X8jYt2w2VicBTOD6gF1veIpS3O6ibibriaGGdKic5dOlBvEF1Y6sLWA%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  通过一个个</span><span style="font-family:宋体;">“小岛”间接的跳转到更远的地址去，使得</span><span style="font-family:Calibri;">jit</span><span style="font-family:宋体;">能支持</span><span style="font-family:Calibri;">512M</span><span style="font-family:宋体;">的内存。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h1><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;"><span style="font-family:Calibri;">2 JIT PAC</span><span style="font-family:宋体;">支持</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;"><o:p></o:p></span></strong></h1><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    Webkit</span><span style="font-family:宋体;">不仅二进制本身使用了</span><span style="font-family:Calibri;">pac</span><span style="font-family:宋体;">技术，还对</span><span style="font-family:Calibri;">JIT code</span><span style="font-family:宋体;">也使能了</span><span style="font-family:Calibri;">pac</span><span style="font-family:宋体;">技术。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">./WTF/wtf/PtrTag.h</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">template</span>&lt;PtrTag tag, <span class="code-snippet__keyword">typename</span> PtrType&gt;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__function">ALWAYS_INLINE <span class="code-snippet__keyword">static</span> PtrType <span class="code-snippet__title">tagNativeCodePtrImpl</span><span class="code-snippet__params">(PtrType ptr)</span></span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> CPU(ARM64E)</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">if</span> <span class="code-snippet__title">constexpr</span> <span class="code-snippet__params">(tag == NoPtrTag)</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> ptr</span>;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">if</span> <span class="code-snippet__title">constexpr</span> <span class="code-snippet__params">(tag == CFunctionPtrTag)</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> <span class="code-snippet__title">ptrauth_sign_unauthenticated</span><span class="code-snippet__params">(ptr, ptrauth_key_function_pointer, <span class="code-snippet__number">0</span>)</span></span>;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">return</span> ptrauth_sign_unauthenticated(ptr, ptrauth_key_process_dependent_code, tag);</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">else</span></span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">return</span> ptr;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    wekit</span><span style="font-family:宋体;">对指针做了标签分类：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">enum</span> PtrTag : <span class="code-snippet__keyword">uintptr_t</span> {</span></code><code><span class="code-snippet_outer">    NoPtrTag,</span></code><code><span class="code-snippet_outer">    CFunctionPtrTag,</span></code><code><span class="code-snippet_outer">};</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;"> 可以看到只对函数指针进行</span><span style="font-family:Calibri;">pac</span><span style="font-family:宋体;">签名。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">template</span>&lt;PtrTag tag, <span class="code-snippet__keyword">typename</span> PtrType&gt;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__function">ALWAYS_INLINE <span class="code-snippet__keyword">static</span> PtrType <span class="code-snippet__title">untagNativeCodePtrImpl</span><span class="code-snippet__params">(PtrType ptr)</span></span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> CPU(ARM64E)</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">if</span> <span class="code-snippet__title">constexpr</span> <span class="code-snippet__params">(tag == NoPtrTag)</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> ptr</span>;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">if</span> <span class="code-snippet__title">constexpr</span> <span class="code-snippet__params">(tag == CFunctionPtrTag)</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> __<span class="code-snippet__title">builtin_ptrauth_auth</span><span class="code-snippet__params">(ptr, ptrauth_key_function_pointer, <span class="code-snippet__number">0</span>)</span></span>;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">return</span> __builtin_ptrauth_auth(ptr, ptrauth_key_process_dependent_code, tag);</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">else</span></span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">return</span> ptr;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  函数指针使用</span><span style="font-family:Calibri;">IA key</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">JavaScriptCore/assembler/MacroAssemblerARM64E.h</span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">MacroAssemblerARM64E</span> :</span> <span class="code-snippet__keyword">public</span> MacroAssemblerARM64 {</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span>:</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">constexpr</span> <span class="code-snippet__keyword">unsigned</span> numberOfPointerBits = <span class="code-snippet__keyword">sizeof</span>(<span class="code-snippet__keyword">void</span>*) * CHAR_BIT;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">constexpr</span> <span class="code-snippet__keyword">unsigned</span> maxNumberOfAllowedPACBits = numberOfPointerBits - OS_CONSTANT(EFFECTIVE_ADDRESS_WIDTH);</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">constexpr</span> <span class="code-snippet__keyword">uintptr_t</span> nonPACBitsMask = (<span class="code-snippet__number">1u</span>ll &lt;&lt; (numberOfPointerBits - maxNumberOfAllowedPACBits)) - <span class="code-snippet__number">1</span>;</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  定义了</span><span style="font-family:Calibri;">pac</span><span style="font-family:宋体;">使用的</span><span style="font-family:Calibri;">bit</span><span style="font-family:宋体;">数。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">    <span class="code-snippet__function">ALWAYS_INLINE <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">tagPtr</span><span class="code-snippet__params">(RegisterID tag, RegisterID target)</span></span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (target == ARM64Registers::lr &amp;&amp; tag == ARM64Registers::sp) {</span></code><code><span class="code-snippet_outer">            m_assembler.pacibsp();</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">return</span>;</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">        m_assembler.pacib(target, tag);</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function">ALWAYS_INLINE <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">untagPtr</span><span class="code-snippet__params">(PtrTag tag, RegisterID target)</span></span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">auto</span> tagGPR = getCachedDataTempRegisterIDAndInvalidate();</span></code><code><span class="code-snippet_outer">        move(TrustedImm64(tag), tagGPR);</span></code><code><span class="code-snippet_outer">        m_assembler.autib(target, tagGPR);</span></code><code><span class="code-snippet_outer">    }</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">  JSC</span><span style="font-family:宋体;">使用了以下</span><span style="font-family:Calibri;">pac</span><span style="font-family:宋体;">指令：</span><span style="font-family:Calibri;">pac*</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">aut*</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">xpac*</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">reta*</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">bra*/blra*</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;"> 同时苹果公司为了防止</span><span style="font-family:Calibri;">pac</span><span style="font-family:宋体;">被绕过的问题，对</span><span style="font-family:Calibri;">webkit</span><span style="font-family:宋体;">以及</span><span style="font-family:Calibri;">xnu</span><span style="font-family:宋体;">内核都使用了</span><span style="font-family:Calibri;">-fptrauth-auth-traps</span><span style="font-family:宋体;">编译选项，以下代码选自</span><span style="font-family:Calibri;">ios16 kernelcache</span><span style="font-family:宋体;">：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="properties"><code><span class="code-snippet_outer"><span class="code-snippet__attr">AUTIA</span>           <span class="code-snippet__string">X16, X17</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">PACIZA</span>          <span class="code-snippet__string">X16</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">MOV</span>             <span class="code-snippet__string">X11, X16</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">XPACI</span>           <span class="code-snippet__string">X11</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">CMP</span>             <span class="code-snippet__string">X11, X9</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">B.CS</span>            <span class="code-snippet__string">loc_FFFFFFF007D3E824</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">B</span>               <span class="code-snippet__string">loc_FFFFFFF007D3E83C</span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    autia</span><span style="font-family:宋体;">检查完毕后，会把</span><span style="font-family:Calibri;">pac</span><span style="font-family:宋体;">去掉，然后使用</span><span style="font-family:Calibri;">xpaci</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">cmp</span><span style="font-family:宋体;">指令在一次做了对比，防止</span><span style="font-family:Calibri;">autia</span><span style="font-family:宋体;">出错。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h1><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;"><span style="font-family:Calibri;">3 GigaCage</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;"><o:p></o:p></span></strong></h1><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    JS</span><span style="font-family:宋体;">语言中的变量会在</span><span style="font-family:Calibri;">JS</span><span style="font-family:宋体;">引擎中抽象为特定的</span><span style="font-family:Calibri;">c</span><span style="font-family:宋体;">语言对象，如果引擎出现漏洞，那么就可通过</span><span style="font-family:Calibri;">js</span><span style="font-family:宋体;">语言操纵这些</span><span style="font-family:Calibri;">c</span><span style="font-family:宋体;">语言对象，是常见的</span><span style="font-family:Calibri;">JS</span><span style="font-family:宋体;">引擎漏洞来源。</span><span style="font-family:Calibri;">Webkit</span><span style="font-family:宋体;">为了缓解这种漏洞攻击，对</span><span style="font-family:Calibri;">Webkit</span><span style="font-family:宋体;">使用的</span><span style="font-family:Calibri;">Heap</span><span style="font-family:宋体;">做了很多安全加固，</span><span style="font-family:Calibri;">GigaCage</span><span style="font-family:宋体;">就是其中一个，用来将</span><span style="font-family:Calibri;">c</span><span style="font-family:宋体;">语言对象限制在一个</span><span style="font-family:Calibri;">4G</span><span style="font-family:宋体;">大小的</span><span style="font-family:Calibri;">cage</span><span style="font-family:宋体;">中，</span><span style="font-family:Calibri;">cage</span><span style="font-family:宋体;">中的对象使用</span><span style="font-family:Calibri;">32</span><span style="font-family:宋体;">位</span><span style="font-family:Calibri;">bit</span><span style="font-family:宋体;">的索引来引用。</span><span style="font-family:Calibri;">GigaCage</span><span style="font-family:宋体;">依附于</span><span style="font-family:Calibri;">bmalloc</span><span style="font-family:宋体;">内存分配器，</span><span style="font-family:Calibri;">webkit</span><span style="font-family:宋体;">中的各种组件都可以使用。它</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"> 它对对象做了如下区分：</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="swift"><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">enum</span> <span class="code-snippet__title">Kind</span> </span>{</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__type">Primitive</span>,</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__type">JSValue</span>,</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__type">NumberOfKinds</span></span></code><code><span class="code-snippet_outer">};</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;"> 当前只分为</span><span style="font-family:Calibri;">Primitive</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">JSValue</span><span style="font-family:宋体;">两大类，未来最多会支持</span><span style="font-family:Calibri;">21</span><span style="font-family:宋体;">个</span><span style="font-family:Calibri;">cage</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;"> 下面看下它是如何初始化建立</span><span style="font-family:Calibri;">Cage</span><span style="font-family:宋体;">区域的：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">bmalloc/bmalloc/Gigacage.<span class="code-snippet__function">cpp</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">void</span> <span class="code-snippet__title">ensureGigacage</span><span class="code-snippet__params">()</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">            Kind shuffledKinds[NumberOfKinds];</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">for</span> (<span class="code-snippet__keyword">unsigned</span> i = <span class="code-snippet__number">0</span>; i &lt; NumberOfKinds; ++i)</span></code><code><span class="code-snippet_outer">                shuffledKinds[i] = <span class="code-snippet__keyword">static_cast</span>&lt;Kind&gt;(i);</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;"> 初始化每个种类的</span><span style="font-family:Calibri;">cage</span><span style="font-family:宋体;">数组。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">uint64_t</span> random;</span></code><code><span class="code-snippet_outer">            cryptoRandom(<span class="code-snippet__keyword">reinterpret_cast</span>&lt;<span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">char</span>*&gt;(&amp;random), <span class="code-snippet__keyword">sizeof</span>(random));</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">for</span> (<span class="code-snippet__keyword">unsigned</span> i = NumberOfKinds; i--;) {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">unsigned</span> limit = i + <span class="code-snippet__number">1</span>;</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">unsigned</span> j = <span class="code-snippet__keyword">static_cast</span>&lt;<span class="code-snippet__keyword">unsigned</span>&gt;(random % limit);</span></code><code><span class="code-snippet_outer">                random /= limit;</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__built_in">std</span>::swap(shuffledKinds[i], shuffledKinds[j]);</span></code><code><span class="code-snippet_outer">            }</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  将</span><span style="font-family:Calibri;">cage</span><span style="font-family:宋体;">数组打乱处理，防止黑客猜测到特定种类</span><span style="font-family:Calibri;">cage</span><span style="font-family:宋体;">的索引。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="nginx"><code><span class="code-snippet_outer">            <span class="code-snippet__attribute">for</span> (Kind kind : shuffledKinds) {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__attribute">totalSize</span> = bump(kind, alignTo(kind, totalSize));</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__attribute">totalSize</span> += runwaySize(kind);</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__attribute">maxAlignment</span> = std::max(maxAlignment, alignment(kind));</span></code><code><span class="code-snippet_outer">            }</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  计算所有</span><span style="font-family:Calibri;">cage</span><span style="font-family:宋体;">需要的内存大小，每个</span><span style="font-family:Calibri;">cage</span><span style="font-family:宋体;">后面加一个</span><span style="font-family:Calibri;">32G</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">guard</span><span style="font-family:宋体;">，因为对象采用</span><span style="font-family:Calibri;">32</span><span style="font-family:宋体;">位大小做索引，每位共</span><span style="font-family:Calibri;">8</span><span style="font-family:宋体;">个</span><span style="font-family:Calibri;">bit</span><span style="font-family:宋体;">，因此最大寻址范围就位</span><span style="font-family:Calibri;">4G*8=32G, </span><span style="font-family:宋体;">即使利用漏洞也只能读取到</span><span style="font-family:Calibri;">guard</span><span style="font-family:宋体;">范围的内存。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">    void* base = tryVMAllocate(maxAlignment, totalSize, VMTag::JSGigacage);</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">分配</span><span style="font-family:Calibri;">cage</span><span style="font-family:宋体;">内存。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">    size_t nextCage = 0;</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;"> 接着从这块大内存中继续划分每个</span><span style="font-family:Calibri;">cage</span><span style="font-family:宋体;">的内存范围。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">for</span> (Kind kind : shuffledKinds) {</span></code><code><span class="code-snippet_outer">                nextCage = alignTo(kind, nextCage);</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">void</span>* gigacageBasePtr = <span class="code-snippet__keyword">reinterpret_cast</span>&lt;<span class="code-snippet__keyword">char</span>*&gt;(base) + nextCage;</span></code><code><span class="code-snippet_outer">                g_gigacageConfig.setBasePtr(kind, gigacageBasePtr);</span></code><code><span class="code-snippet_outer">                nextCage = bump(kind, nextCage);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">uint64_t</span> random[<span class="code-snippet__number">2</span>];</span></code><code><span class="code-snippet_outer">                cryptoRandom(<span class="code-snippet__keyword">reinterpret_cast</span>&lt;<span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">char</span>*&gt;(random), <span class="code-snippet__keyword">sizeof</span>(random));</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;"> 随机产生了两个</span><span style="font-family:Calibri;">64bit</span><span style="font-family:宋体;">随机数。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">size_t</span> gigacageSize = maxSize(kind);</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">size_t</span> size = roundDownToMultipleOf(vmPageSize(), gigacageSize - (random[<span class="code-snippet__number">0</span>] % maximumCageSizeReductionForSlide));</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  第一个随机数用来生成</span><span style="font-family:Calibri;">cage</span><span style="font-family:宋体;">的大小。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">maximumCageSizeReductionForSlide</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">被设置为</span><span style="font-family:Calibri;">1G</span><span style="font-family:宋体;">或</span><span style="font-family:Calibri;">4G</span><span style="font-family:宋体;">大小。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">    g_gigacageConfig.setAllocSize(kind, size);</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">    g_gigacageConfig</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">.basePtrs</span><span style="font-family:宋体;">数组保存了每个</span><span style="font-family:Calibri;">cage</span><span style="font-family:宋体;">的起始地址。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">ptrdiff_t</span> offset = roundDownToMultipleOf(vmPageSize(), random[<span class="code-snippet__number">1</span>] % (gigacageSize - size));</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">void</span>* thisBase = <span class="code-snippet__keyword">reinterpret_cast</span>&lt;<span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">char</span>*&gt;(gigacageBasePtr) + offset;</span></code><code><span class="code-snippet_outer">                g_gigacageConfig.setAllocBasePtr(kind, thisBase);</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  第二个随机数用于计算</span><span style="font-family:Calibri;">cage</span><span style="font-family:宋体;">的起始地址，可以看到两个</span><span style="font-family:Calibri;">cage</span><span style="font-family:宋体;">之间除了</span><span style="font-family:Calibri;">32G</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">guard</span><span style="font-family:宋体;">内存，还有一个随机化过的起始地址，这样猜测使猜测一个</span><span style="font-family:Calibri;">cage</span><span style="font-family:宋体;">的地址更加困难。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    GigaCage</span><span style="font-family:宋体;">定义了</span><span style="font-family:Calibri;">caged</span><span style="font-family:宋体;">接口用于访问一个指针：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">bmalloc/bmalloc/Gigacage.h</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">template</span>&lt;<span class="code-snippet__keyword">typename</span> T&gt;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__function">BINLINE T* <span class="code-snippet__title">caged</span><span class="code-snippet__params">(Kind kind, T* ptr)</span></span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">    BASSERT(ptr);</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span> (!isEnabled(kind))</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> ptr;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">void</span>* gigacageBasePtr = basePtr(kind);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">return</span> <span class="code-snippet__keyword">reinterpret_cast</span>&lt;T*&gt;(</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">reinterpret_cast</span>&lt;<span class="code-snippet__keyword">uintptr_t</span>&gt;(gigacageBasePtr) + (</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">reinterpret_cast</span>&lt;<span class="code-snippet__keyword">uintptr_t</span>&gt;(ptr) &amp; mask(kind)));</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  根据</span><span style="font-family:Calibri;">kind</span><span style="font-family:宋体;">提取</span><span style="font-family:Calibri;">cage</span><span style="font-family:宋体;">基地址，在加上一个</span><span style="font-family:Calibri;">mask</span><span style="font-family:宋体;">后的</span><span style="font-family:Calibri;">32</span><span style="font-family:宋体;">位索引。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  以下对象都使用了</span><span style="font-family:Calibri;">cage</span><span style="font-family:宋体;">进行防护：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">./JavaScriptCore/runtime/ArrayBuffer.h:    <span class="code-snippet__keyword">using</span> DataType = CagedPtr&lt;Gigacage::Primitive, <span class="code-snippet__keyword">void</span>, tagCagedPtr&gt;;</span></code><code><span class="code-snippet_outer">./JavaScriptCore/runtime/JSBigInt.h:    CagedBarrierPtr&lt;Gigacage::Primitive, Digit, tagCagedPtr&gt; m_data;</span></code><code><span class="code-snippet_outer">./JavaScriptCore/runtime/BufferMemoryHandle.h:    <span class="code-snippet__keyword">using</span> CagedMemory = CagedPtr&lt;Gigacage::Primitive, <span class="code-snippet__keyword">void</span>, tagCagedPtr&gt;;</span></code><code><span class="code-snippet_outer">./JavaScriptCore/runtime/ArrayBufferView.h:    <span class="code-snippet__keyword">using</span> BaseAddress = CagedPtr&lt;Gigacage::Primitive, <span class="code-snippet__keyword">void</span>, tagCagedPtr&gt;;</span></code><code><span class="code-snippet_outer">./JavaScriptCore/runtime/JSArrayBufferView.h:    <span class="code-snippet__keyword">using</span> VectorPtr = CagedBarrierPtr&lt;Gigacage::Primitive, <span class="code-snippet__keyword">void</span>, tagCagedPtr&gt;;</span></code></pre></section><h1><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;"><span style="font-family:Calibri;">4 jitcage</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;"><o:p></o:p></span></strong></h1><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  苹果为了增强</span><span style="font-family:Calibri;">JIT</span><span style="font-family:宋体;">的安全防护能力，又增加了一个叫做</span><span style="font-family:Calibri;">jitcage</span><span style="font-family:宋体;">的防护技术，目前能</span><span style="font-family:Calibri;">google</span><span style="font-family:宋体;">到的关于它的分析，只有</span><span style="font-family:Calibri;">synacktiv</span><span style="font-family:宋体;">的安全研究员在</span><span style="font-family:Calibri;">2022</span><span style="font-family:宋体;">年的一篇</span><span style="font-family:Calibri;">paper</span><span style="font-family:宋体;">中有相对详细的介绍《</span><span style="font-family:Calibri;">attacking safari in 2022</span><span style="font-family:宋体;">》。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  类似于</span><span style="font-family:Calibri;">aprr</span><span style="font-family:宋体;">，苹果公司又增加了新的硬件安全机制来保护特定的</span><span style="font-family:Calibri;">jit</span><span style="font-family:宋体;">区域，按照</span><span style="font-family:Calibri;">synacktiv</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">paper</span><span style="font-family:宋体;">，在此区域里的</span><span style="font-family:Calibri;">jit code</span><span style="font-family:宋体;">不能执行以下指令：</span><span style="font-family:Calibri;">ret</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">br/blr/bl</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">svc</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">mrs/msr</span><span style="font-family:宋体;">。由于笔者只通过</span><span style="font-family:Calibri;">webkit</span><span style="font-family:宋体;">的源码和部分二进制做了静态分析，以上</span><span style="font-family:Calibri;">synacktiv</span><span style="font-family:宋体;">给出的结论应该是动态调试的推论，笔者无法验证。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">  Jitcage</span><span style="font-family:宋体;">需要苹果公司授权一个特殊的</span><span style="font-family:Calibri;">entitlement</span><span style="font-family:宋体;">：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">&#34;com.apple.private.verified-jit&#34;</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">，这是一个未公开的</span><span style="font-family:Calibri;">entitlement</span><span style="font-family:宋体;">，我们可以在</span><span style="font-family:Calibri;">javascriptcore</span><span style="font-family:宋体;">的源码中看到有对它的引用：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">./JavaScriptCore/runtime/Options.cpp</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> ENABLE(JIT_CAGE)</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__function">SUPPRESS_ASAN <span class="code-snippet__keyword">bool</span> <span class="code-snippet__title">canUseJITCage</span><span class="code-snippet__params">()</span></span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span> (JSC_FORCE_USE_JIT_CAGE)</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> <span class="code-snippet__literal">true</span>;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">return</span> JSC_JIT_CAGE_VERSION() &amp;&amp; WTF::processHasEntitlement(<span class="code-snippet__string">&#34;com.apple.private.verified-jit&#34;</span>_s);</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><h2><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">4.1 jitcage</span><span style="font-family:黑体;">内存初始化</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:Arial;mso-fareast-font-family:黑体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    Jitcage</span><span style="font-family:宋体;">的一个功能是修改了</span><span style="font-family:Calibri;">kernel</span><span style="font-family:宋体;">中的</span><span style="font-family:Calibri;">mmap</span><span style="font-family:宋体;">接口，当在某一条件下，它会申请一块特殊的内存，这块特殊的内存如上所述，会得到硬件的保护。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">__int64 __<span class="code-snippet__function">fastcall <span class="code-snippet__title">mmap</span><span class="code-snippet__params">(proc *a1, __int64 a2, _QWORD *a3)</span></span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">      <span class="code-snippet__keyword">if</span> ( !(<span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">int</span>)IOTaskHasEntitlement(<span class="code-snippet__number">0</span>, <span class="code-snippet__string">&#34;com.apple.private.verified-jit&#34;</span>) )</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">goto</span> LABEL_196;</span></code><code><span class="code-snippet_outer">      v73 = sub_FFFFFFF007EC3B64(v5, &amp;v102, (__int64)ctxa, v66, v89, v42, v70, v101);</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  首先要判断当前进程是否有</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">&#34;com.apple.private.verified-jit&#34;</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">这个</span><span style="font-family:Calibri;">entitlement</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">__int64 __<span class="code-snippet__function">fastcall <span class="code-snippet__title">sub_FFFFFFF007EC3B64</span><span class="code-snippet__params">(</span></span></span></code><code><span class="code-snippet_outer">        __int64 a1,</span></code><code><span class="code-snippet_outer">        __int64 *a2,</span></code><code><span class="code-snippet_outer">        __int64 a3,</span></code><code><span class="code-snippet_outer">        __int64 a4,</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">int</span> a5,</span></code><code><span class="code-snippet_outer">        __int64 a6,</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">int</span> a7,</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">int</span> a8)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">  v10 = vm_map_enter_mem_object(                <span class="code-snippet__comment">// kern_return_t</span></span></code><code><span class="code-snippet_outer">                                                <span class="code-snippet__comment">// vm_map_enter_mem_object(</span></span></code><code><span class="code-snippet_outer">                                                <span class="code-snippet__comment">//     vm_map_t                target_map,</span></span></code><code><span class="code-snippet_outer">                                                <span class="code-snippet__comment">//     vm_map_offset_t         *address,</span></span></code><code><span class="code-snippet_outer">                                                <span class="code-snippet__comment">//     vm_map_size_t           initial_size,</span></span></code><code><span class="code-snippet_outer">                                                <span class="code-snippet__comment">//     vm_map_offset_t         mask,</span></span></code><code><span class="code-snippet_outer">                                                <span class="code-snippet__comment">//     int                     flags,</span></span></code><code><span class="code-snippet_outer">                                                <span class="code-snippet__comment">//     vm_map_kernel_flags_t   vmk_flags,</span></span></code><code><span class="code-snippet_outer">                                                <span class="code-snippet__comment">//     vm_tag_t                tag,</span></span></code><code><span class="code-snippet_outer">                                                <span class="code-snippet__comment">//     ipc_port_t              port,</span></span></code><code><span class="code-snippet_outer">                                                <span class="code-snippet__comment">//     vm_object_offset_t      offset,</span></span></code><code><span class="code-snippet_outer">                                                <span class="code-snippet__comment">//     boolean_t               copy,</span></span></code><code><span class="code-snippet_outer">                                                <span class="code-snippet__comment">//     vm_prot_t               cur_protection,</span></span></code><code><span class="code-snippet_outer">                                                <span class="code-snippet__comment">//     vm_prot_t               max_protection,</span></span></code><code><span class="code-snippet_outer">                                                <span class="code-snippet__comment">//     vm_inherit_t            inheritance)</span></span></code><code><span class="code-snippet_outer">          a1,</span></code><code><span class="code-snippet_outer">          &amp;v31,</span></code><code><span class="code-snippet_outer">          v9,</span></code><code><span class="code-snippet_outer">          <span class="code-snippet__number">0L</span>L,</span></code><code><span class="code-snippet_outer">          a4 &amp; <span class="code-snippet__number">0xFFFFBFFE</span> | <span class="code-snippet__number">0x4000</span>,</span></code><code><span class="code-snippet_outer">          a5 &amp; <span class="code-snippet__number">0xFFFFFEEE</span> | <span class="code-snippet__number">0x111</span>LL,</span></code><code><span class="code-snippet_outer">          a6,</span></code><code><span class="code-snippet_outer">          <span class="code-snippet__number">0L</span>L,</span></code><code><span class="code-snippet_outer">          <span class="code-snippet__number">0L</span>L,</span></code><code><span class="code-snippet_outer">          v28,</span></code><code><span class="code-snippet_outer">          a8 | <span class="code-snippet__number">0x100000000</span>LL,</span></code><code><span class="code-snippet_outer">          <span class="code-snippet__number">0L</span>L,</span></code><code><span class="code-snippet_outer">          <span class="code-snippet__number">0</span>);</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">if</span> ( !(_DWORD)v10 )</span></code><code><span class="code-snippet_outer">  {</span></code><code><span class="code-snippet_outer">    v26 = v31;</span></code><code><span class="code-snippet_outer">    *(_QWORD *)(v30 + <span class="code-snippet__number">0x348</span>) = v31 &amp; <span class="code-snippet__number">0x1FFFFFE000000</span>LL | (<span class="code-snippet__number">7</span> - (<span class="code-snippet__keyword">unsigned</span> __int8)__clz(v9 - <span class="code-snippet__number">1</span>)) &amp; <span class="code-snippet__number">0xF</span>;</span></code><code><span class="code-snippet_outer">    *(_QWORD *)(v30 + <span class="code-snippet__number">0x350</span>) = <span class="code-snippet__number">0x100C5B</span>LL;      <span class="code-snippet__comment">// 1m</span></span></code><code><span class="code-snippet_outer">    address[<span class="code-snippet__number">2</span>] = v30;</span></code><code><span class="code-snippet_outer">    v33 = <span class="code-snippet__number">0L</span>L;</span></code><code><span class="code-snippet_outer">    address[<span class="code-snippet__number">1</span>] = (<span class="code-snippet__keyword">mach_vm_address_t</span>)enable_jitbox;</span></code><code><span class="code-snippet_outer">    sub_FFFFFFF007EA4720(<span class="code-snippet__number">4</span>, &amp;v33);</span></code><code><span class="code-snippet_outer">    *a2 = v26;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">return</span> v10;</span></code><code><span class="code-snippet_outer">  }</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  首先调用</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">vm_map_enter_mem_object</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">分配一块内存，然后将地址存入</span><span style="font-family:Calibri;">current thread</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">0x348</span><span style="font-family:宋体;">地址，</span><span style="font-family:Calibri;">0x350</span><span style="font-family:宋体;">限制了这块内存的大小为</span><span style="font-family:Calibri;">1M</span><span style="font-family:宋体;">。内核会在某一时刻调用</span><span style="font-family:Calibri;">enable_jitbox</span><span style="font-family:宋体;">函数。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="properties"><code><span class="code-snippet_outer"><span class="code-snippet__attr">void</span> <span class="code-snippet__string">__fastcall enable_jitbox(__int64 a1)</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">{</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__attr">__int64</span> <span class="code-snippet__string">v2; // x0</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__attr">__int64</span> <span class="code-snippet__string">v3; // x8</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__attr">unsigned</span> <span class="code-snippet__string">__int64 StatusReg; // x9</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__attr">v2</span> = <span class="code-snippet__string">current_task();</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__attr">if</span> <span class="code-snippet__string">( v2 == a1 )</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__attr">{</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">v3</span> = <span class="code-snippet__string">*(_QWORD *)(v2 + 848);</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">StatusReg</span> = <span class="code-snippet__string">_ReadStatusReg(ARM64_SYSREG(3, 0, 13, 0, 4));</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__meta">*(_QWORD</span> <span class="code-snippet__string">*)(*(_QWORD *)(StatusReg + 336) + 536LL) = v3;</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__meta">*(_QWORD</span> <span class="code-snippet__string">*)(*(_QWORD *)(StatusReg + 336) + 528LL) = *(_QWORD *)(v2 + 840);</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__meta">_WriteStatusReg(ARM64_SYSREG(3,</span> <span class="code-snippet__string">4, 15, 15, 4), *(_QWORD *)(v2 + 848));</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__meta">_WriteStatusReg(ARM64_SYSREG(3,</span> <span class="code-snippet__string">4, 15, 15, 1), *(_QWORD *)(v2 + 840));</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">__isb(0xFu);</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__attr">}</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">}</span></span></code></pre></section><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">LDR</span>             <span class="code-snippet__selector-tag">X8</span>, <span class="code-snippet__selector-attr">[X0,#0x350]</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">MSR</span>             <span class="code-snippet__selector-id">#4</span>, <span class="code-snippet__selector-tag">c15</span>, <span class="code-snippet__selector-tag">c15</span>, <span class="code-snippet__selector-id">#4</span>, <span class="code-snippet__selector-tag">X8</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">LDR</span>             <span class="code-snippet__selector-tag">X8</span>, <span class="code-snippet__selector-attr">[X0,#0x348]</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">MSR</span>             <span class="code-snippet__selector-id">#4</span>, <span class="code-snippet__selector-tag">c15</span>, <span class="code-snippet__selector-tag">c15</span>, <span class="code-snippet__selector-id">#1</span>, <span class="code-snippet__selector-tag">X8</span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">    0x348</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">代表</span><span style="font-family:Calibri;">jitcage</span><span style="font-family:宋体;">内存地址，</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">0x3</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">50</span><span style="font-family:宋体;">代表其大小，分别写入两个不同的寄存器中。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h2><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">4.2 jitcage</span><span style="font-family:黑体;">对</span><span style="font-family:Arial;">bytecode</span><span style="font-family:黑体;">表保护</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  苹果公司只公开了部分的</span><span style="font-family:Calibri;">jitcage</span><span style="font-family:宋体;">源码，通过关键字</span><span style="font-family:Calibri;">JIT_CAGE</span><span style="font-family:宋体;">搜寻</span><span style="font-family:Calibri;">webkit</span><span style="font-family:宋体;">的源码，可以看到在</span><span style="font-family:Calibri;">jsc</span><span style="font-family:宋体;">初始化</span><span style="font-family:Calibri;">bytecode</span><span style="font-family:宋体;">操作表的时候引用了</span><span style="font-family:Calibri;">jitcage</span><span style="font-family:宋体;">的另一个功能。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">./JavaScriptCore/assembler/JITOperationList.cpp</span></code><code><span class="code-snippet_outer">SUPPRESS_ASAN ALWAYS_INLINE <span class="code-snippet__keyword">void</span> JITOperationList::addPointers(<span class="code-snippet__keyword">const</span> JITOperationAnnotation* begin, <span class="code-snippet__keyword">const</span> JITOperationAnnotation* end)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">auto</span>&amp; <span class="code-snippet__built_in">map</span> = m_validatedOperations;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> ENABLE(JIT_CAGE)</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span> (Options::useJITCage()) {</span></code><code><span class="code-snippet_outer">        JSC_JIT_CAGED_POINTER_REGISTRATION();</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span>;</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">if</span> <span class="code-snippet__title">constexpr</span> <span class="code-snippet__params">(JIT_OPERATION_VALIDATION_ASSERT_ENABLED)</span> </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">for</span> (<span class="code-snippet__keyword">const</span> <span class="code-snippet__keyword">auto</span>* current = begin; current != end; ++current) {</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">void</span>* operation = removeCodePtrTag(current-&gt;operation);</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">if</span> (operation) {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">void</span>* validator = removeCodePtrTag(Options::useJITCage() ? current-&gt;operationWithValidation : current-&gt;operation);</span></code><code><span class="code-snippet_outer">                validator = WTF::tagNativeCodePtrImpl&lt;OperationPtrTag&gt;(validator);</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__built_in">map</span>.add(operation, validator);</span></code><code><span class="code-snippet_outer">                JSC_REGISTER_INVERSE_JIT_CAGED_POINTER_FOR_DEBUG(validator, operation);</span></code><code><span class="code-snippet_outer">            }</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">void</span> JITOperationList::populatePointersInJavaScriptCore()</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">static</span> <span class="code-snippet__built_in">std</span>::once_flag onceKey;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__built_in">std</span>::call_once(onceKey, [] {</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (Options::useJIT())</span></code><code><span class="code-snippet_outer">            jitOperationList-&gt;addPointers(&amp;startOfJITOperationsInJSC, &amp;endOfJITOperationsInJSC);</span></code><code><span class="code-snippet_outer">#<span class="code-snippet__keyword">if</span> ENABLE(JIT_OPERATION_DISASSEMBLY)</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (UNLIKELY(Options::needDisassemblySupport()))</span></code><code><span class="code-snippet_outer">            populateDisassemblyLabelsInJavaScriptCore();</span></code><code><span class="code-snippet_outer">#endif</span></code><code><span class="code-snippet_outer">    });</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">    JSC_JIT_CAGED_POINTER_REGISTRATION()</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">在源码中被抹掉了，通过分析二进制可以看到它的实现：</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="ruby"><code><span class="code-snippet_outer">__int64 __fastcall JSC::initialize(void)<span class="code-snippet__symbol">:</span><span class="code-snippet__symbol">:</span>$_7<span class="code-snippet__symbol">:</span><span class="code-snippet__symbol">:operator</span>()(WTF *a1)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">  v11 = (JSC *)JSC::JITOperationList::populatePointersInJavaScriptCore(v7, v8, v9, v1<span class="code-snippet__number">0</span>);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">void __fastcall std::__call_once_proxy&lt;std::tuple&lt;JSC::JITOperationList::populatePointersInJavaScriptCore(void)<span class="code-snippet__symbol">:</span><span class="code-snippet__symbol">:</span>$_3 &amp;&amp;<span class="code-snippet__meta">&gt;&gt;</span>(</span></code><code><span class="code-snippet_outer">        __int64 a1,</span></code><code><span class="code-snippet_outer">        unsigned __int64 a2)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">v4 = (WTF *)WTF::fastMalloc((WTF *)<span class="code-snippet__number">0x2980</span>, a2);</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"> 为操作表分配内存。</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js"><code><span class="code-snippet_outer">_WriteStatusReg(ARM64_SYSREG(3, 4, 15, 15, 6), _ReadStatusReg(ARM64_SYSREG(3, 4, 15, 15, 6)) | 0x8000);</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  将特殊寄存器第</span><span style="font-family:Calibri;">15bit</span><span style="font-family:宋体;">置</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="properties"><code><span class="code-snippet_outer">    <span class="code-snippet__attr">__isb(0xFu);</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">if</span> <span class="code-snippet__string">( useJIT )</span></span></code><code><span class="code-snippet_outer">      <span class="code-snippet__attr">__break(0xC471u);</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">v5</span> = <span class="code-snippet__string">0;</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">v6</span> = <span class="code-snippet__string">&amp;JSC::_JITTargetID_ctiMasmProbeTrampoline;</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">do</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">{</span></span></code><code><span class="code-snippet_outer">      <span class="code-snippet__attr">if</span> <span class="code-snippet__string">( *v6 )</span></span></code><code><span class="code-snippet_outer">      <span class="code-snippet__attr">{</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__attr">v7</span> = <span class="code-snippet__string">v6[1];</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__attr">v8</span> = <span class="code-snippet__string">(__int64 *)((char *)v4 + 16 * v5);</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__meta">*v8</span> = <span class="code-snippet__string">*v6;</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__meta">v8[1]</span> = <span class="code-snippet__string">v7;</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__attr">++v5;</span></span></code><code><span class="code-snippet_outer">      <span class="code-snippet__attr">}</span></span></code><code><span class="code-snippet_outer">      <span class="code-snippet__attr">v6</span> <span class="code-snippet__string">+= 2;</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">}</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">while</span> <span class="code-snippet__string">( v6 != (__int64 *)&amp;`vtable for&#39;CrashLogPrintStream );</span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"> 对操作表进行赋值。</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="objectivec"><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span> ( useJIT )</span></code><code><span class="code-snippet_outer">      __<span class="code-snippet__keyword">break</span>(<span class="code-snippet__number">0xC471</span>u);</span></code><code><span class="code-snippet_outer">_WriteStatusReg(ARM64_SYSREG(<span class="code-snippet__number">3</span>, <span class="code-snippet__number">4</span>, <span class="code-snippet__number">15</span>, <span class="code-snippet__number">15</span>, <span class="code-snippet__number">6</span>), _ReadStatusReg(ARM64_SYSREG(<span class="code-snippet__number">3</span>, <span class="code-snippet__number">4</span>, <span class="code-snippet__number">15</span>, <span class="code-snippet__number">15</span>, <span class="code-snippet__number">6</span>)) &amp; <span class="code-snippet__number">0xFFFFFFFFFFFF7FFF</span>LL);</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  将特殊寄存器第</span><span style="font-family:Calibri;">15bit</span><span style="font-family:宋体;">清</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  可以推测出这个寄存器实现了上锁与解锁的功能。这个</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">__break(0xC471u)</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">指令有特殊的功效，它防止</span><span style="font-family:Calibri;">jitcode</span><span style="font-family:宋体;">中调用和修改这个寄存器，如果有以上行为就会触发一个断点操作被内核捕获。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h2><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">4.3 PAC key</span><span style="font-family:黑体;">的保护</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  这里的</span><span style="font-family:Calibri;">key</span><span style="font-family:宋体;">指的是</span><span style="font-family:Calibri;">brab</span><span style="font-family:宋体;">指令的第一个参数，在挑战到目标地址时，利用</span><span style="font-family:Calibri;">pac</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">b key</span><span style="font-family:宋体;">以及这个特殊的参数做指针完整性判断。我们可以在</span><span style="font-family:Calibri;">webkit</span><span style="font-family:宋体;">生成</span><span style="font-family:Calibri;">machine code</span><span style="font-family:宋体;">时看到对它的一些引用：</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="ruby"><code><span class="code-snippet_outer">JavaScriptCore/assembler/MacroAssemblerARM64E.h</span></code><code><span class="code-snippet_outer">    ALWAYS_INLINE Jump jump() { <span class="code-snippet__keyword">return</span> MacroAssemblerARM64::jump(); }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    template&lt;JumpSignatureType type&gt;</span></code><code><span class="code-snippet_outer">    ALWAYS_INLINE void farJumpRegister(RegisterID targetGPR, RegisterID tagGPR = InvalidGPR)</span></code><code><span class="code-snippet_outer">    {</span></code><code><span class="code-snippet_outer">        UNUSED_PARAM(type);</span></code><code><span class="code-snippet_outer">        ASSERT(tagGPR != targetGPR);</span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">#if ENABLE(JIT_CAGE)</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (Options::useJITCage()) {</span></code><code><span class="code-snippet_outer">            JSC_JIT_CAGED_FAR_JUMP(type, targetGPR, tagGPR);</span></code><code><span class="code-snippet_outer">        } <span class="code-snippet__keyword">else</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">#endif</span></span></code><code><span class="code-snippet_outer">            m_assembler.brab(targetGPR, tagGPR);</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    void farJump(RegisterID targetGPR, PtrTag tag)</span></code><code><span class="code-snippet_outer">    {</span></code><code><span class="code-snippet_outer">        ASSERT(tag != CFunctionPtrTag &amp;&amp; tag != NoPtrTag);</span></code><code><span class="code-snippet_outer">        ASSERT(!Options::useJITCage() <span class="code-snippet__params">||</span> callerType(tag) == PtrTagCallerType::JIT);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        ASSERT(tag != CFunctionPtrTag);</span></code><code><span class="code-snippet_outer">        RegisterID diversityGPR = getCachedDataTempRegisterIDAndInvalidate();</span></code><code><span class="code-snippet_outer">        move(TrustedImm64(tag), diversityGPR);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (calleeType(tag) == PtrTagCalleeType::JIT)</span></code><code><span class="code-snippet_outer">            farJumpRegister&lt;JumpSignatureType::JITJump&gt;(targetGPR, diversityGPR);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">else</span></span></code><code><span class="code-snippet_outer">            farJumpRegister&lt;JumpSignatureType::NativeJump&gt;(targetGPR, diversityGPR);</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style="margin-left: 21pt;"><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">JSC_JIT_CAGED_FAR_JUMP</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">函数在源码中被抹掉了，通过查看反汇编代码：</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="php"><code><span class="code-snippet_outer">_int64 __fastcall JSC::MacroAssemblerARM64E::farJump(__int64 a1, int a2, JSC::ARM64LogicalImmediate *a3)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">if</span> ( (__int64)a3 &gt; <span class="code-snippet__number">0xC344</span> )</span></code><code><span class="code-snippet_outer">  {</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span> ( (__int64)a3 &gt; <span class="code-snippet__number">0xE015</span> )</span></code><code><span class="code-snippet_outer">    {</span></code><code><span class="code-snippet_outer">      <span class="code-snippet__keyword">if</span> ( a3 == (JSC::ARM64LogicalImmediate *)<span class="code-snippet__number">0xE016</span> || a3 == (JSC::ARM64LogicalImmediate *)<span class="code-snippet__number">0xED60</span> )</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">goto</span> LABEL_17;</span></code><code><span class="code-snippet_outer">      v8 = <span class="code-snippet__number">0xE314</span>LL;</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">else</span></span></code><code><span class="code-snippet_outer">    {</span></code><code><span class="code-snippet_outer">      v8 = <span class="code-snippet__number">0xC345</span>LL;</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">  }</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">else</span> <span class="code-snippet__keyword">if</span> ( (__int64)a3 &lt;= <span class="code-snippet__number">0x94D0</span> )</span></code><code><span class="code-snippet_outer">  {</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span> ( (__int64)a3 &lt;= <span class="code-snippet__number">0xDA8</span> )</span></code><code><span class="code-snippet_outer">    {</span></code><code><span class="code-snippet_outer">      <span class="code-snippet__keyword">if</span> ( a3 != (JSC::ARM64LogicalImmediate *)<span class="code-snippet__number">0x593</span> )</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">goto</span> LABEL_10;</span></code><code><span class="code-snippet_outer">      <span class="code-snippet__keyword">goto</span> LABEL_17;</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span> ( (__int64)a3 &gt; <span class="code-snippet__number">0x47E9</span> )</span></code><code><span class="code-snippet_outer">    {</span></code><code><span class="code-snippet_outer">      <span class="code-snippet__keyword">if</span> ( (__int64)a3 &lt;= <span class="code-snippet__number">0x6F9A</span> )</span></code><code><span class="code-snippet_outer">      {</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> ( (__int64)a3 &lt;= <span class="code-snippet__number">0x5CAC</span> )</span></code><code><span class="code-snippet_outer">        {</span></code><code><span class="code-snippet_outer">          <span class="code-snippet__keyword">if</span> ( a3 == (JSC::ARM64LogicalImmediate *)<span class="code-snippet__number">0x4D56</span> || a3 == (JSC::ARM64LogicalImmediate *)<span class="code-snippet__number">0x47EA</span> )</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">goto</span> LABEL_17;</span></code><code><span class="code-snippet_outer">          v8 = <span class="code-snippet__number">0x5689</span>LL;</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">else</span></span></code><code><span class="code-snippet_outer">        {</span></code><code><span class="code-snippet_outer">          <span class="code-snippet__keyword">if</span> ( a3 == (JSC::ARM64LogicalImmediate *)<span class="code-snippet__number">0x5D3F</span> || a3 == (JSC::ARM64LogicalImmediate *)<span class="code-snippet__number">0x5CAD</span> )</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">goto</span> LABEL_17;</span></code><code><span class="code-snippet_outer">          v8 = <span class="code-snippet__number">0x6813</span>LL;</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">      }</span></code><code><span class="code-snippet_outer">      <span class="code-snippet__keyword">else</span> <span class="code-snippet__keyword">if</span> ( (__int64)a3 &gt; <span class="code-snippet__number">0x7F71</span> )</span></code><code><span class="code-snippet_outer">      {</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> ( a3 == (JSC::ARM64LogicalImmediate *)<span class="code-snippet__number">0x7F72</span> || a3 == (JSC::ARM64LogicalImmediate *)<span class="code-snippet__number">0x8763</span> )</span></code><code><span class="code-snippet_outer">          <span class="code-snippet__keyword">goto</span> LABEL_17;</span></code><code><span class="code-snippet_outer">        v8 = <span class="code-snippet__number">0x90C4</span>LL;</span></code><code><span class="code-snippet_outer">      }</span></code><code><span class="code-snippet_outer">      <span class="code-snippet__keyword">else</span></span></code><code><span class="code-snippet_outer">      {</span></code><code><span class="code-snippet_outer">        v8 = <span class="code-snippet__number">0x6F9B</span>LL;</span></code><code><span class="code-snippet_outer">      }</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">else</span></span></code><code><span class="code-snippet_outer">    {</span></code><code><span class="code-snippet_outer">      <span class="code-snippet__keyword">if</span> ( a3 == (JSC::ARM64LogicalImmediate *)<span class="code-snippet__number">0xDA9</span> || a3 == (JSC::ARM64LogicalImmediate *)<span class="code-snippet__number">0x24AD</span> )</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">goto</span> LABEL_17;</span></code><code><span class="code-snippet_outer">      v8 = <span class="code-snippet__number">0x1DDD</span>LL;</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">  }</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">else</span></span></code><code><span class="code-snippet_outer">  {</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span> ( a3 == (JSC::ARM64LogicalImmediate *)<span class="code-snippet__number">0xBA68</span> || a3 == (JSC::ARM64LogicalImmediate *)<span class="code-snippet__number">0x94D1</span> )</span></code><code><span class="code-snippet_outer">      <span class="code-snippet__keyword">goto</span> LABEL_17;</span></code><code><span class="code-snippet_outer">    v8 = <span class="code-snippet__number">0x96FD</span>LL;</span></code><code><span class="code-snippet_outer">  }</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    a3</span><span style="font-family:宋体;">代表</span><span style="font-family:Calibri;">brab</span><span style="font-family:宋体;">的第一个参数，可以看到</span><span style="font-family:Calibri;">jitcage</span><span style="font-family:宋体;">的意图是限制了</span><span style="font-family:Calibri;">brab</span><span style="font-family:宋体;">这个参数的范围，根据不同的汇编指令只允许使用对应的值。通过对整个</span><span style="font-family:Calibri;">jsc binary</span><span style="font-family:宋体;">进行搜寻可以证明：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018B991760</span>                 <span class="code-snippet__selector-tag">ADRL</span>            <span class="code-snippet__selector-tag">X7</span>, _<span class="code-snippet__selector-tag">g_config</span></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018B991768</span>                 <span class="code-snippet__selector-tag">ADD</span>             <span class="code-snippet__selector-tag">X7</span>, <span class="code-snippet__selector-tag">X7</span>, <span class="code-snippet__selector-id">#0xC28</span></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018B99176C</span>                 <span class="code-snippet__selector-tag">MOV</span>             <span class="code-snippet__selector-tag">X17</span>, <span class="code-snippet__selector-id">#0xE016</span></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018B991770</span>                 <span class="code-snippet__selector-tag">LDR</span>             <span class="code-snippet__selector-tag">X13</span>, <span class="code-snippet__selector-attr">[X7]</span></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018B991774</span>                 <span class="code-snippet__selector-tag">BRAB</span>            <span class="code-snippet__selector-tag">X13</span>, <span class="code-snippet__selector-tag">X17</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018B9919C0</span></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018B9919C0</span>                 <span class="code-snippet__selector-tag">PACIBSP</span></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018B9919C4</span>                 <span class="code-snippet__selector-tag">STP</span>             <span class="code-snippet__selector-tag">X29</span>, <span class="code-snippet__selector-tag">X30</span>, <span class="code-snippet__selector-attr">[SP,#-0x10+var_s0]</span>!</span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018B9919C8</span>                 <span class="code-snippet__selector-tag">MOV</span>             <span class="code-snippet__selector-tag">X29</span>, <span class="code-snippet__selector-tag">SP</span></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018B9919CC</span>                 <span class="code-snippet__selector-tag">MOV</span>             <span class="code-snippet__selector-tag">X13</span>, <span class="code-snippet__selector-id">#0x8763</span></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018B9919D0</span>                 <span class="code-snippet__selector-tag">BRAB</span>            <span class="code-snippet__selector-tag">X5</span>, <span class="code-snippet__selector-tag">X13</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018B9919DC</span>                 <span class="code-snippet__selector-tag">MOV</span>             <span class="code-snippet__selector-tag">X13</span>, <span class="code-snippet__selector-id">#0x153F</span></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018B9919E0</span>                 <span class="code-snippet__selector-tag">BRAB</span>            <span class="code-snippet__selector-tag">X3</span>, <span class="code-snippet__selector-tag">X13</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018B9919EC</span>                 <span class="code-snippet__selector-tag">MOV</span>             <span class="code-snippet__selector-tag">X13</span>, <span class="code-snippet__selector-id">#0x4911</span></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018B9919F0</span>                 <span class="code-snippet__selector-tag">BRAB</span>            <span class="code-snippet__selector-tag">X2</span>, <span class="code-snippet__selector-tag">X13</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018B991A00</span>                 <span class="code-snippet__selector-tag">MOV</span>             <span class="code-snippet__selector-tag">X13</span>, <span class="code-snippet__selector-id">#0x90C4</span></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018B991A04</span>                 <span class="code-snippet__selector-tag">BRAB</span>            <span class="code-snippet__selector-tag">X3</span>, <span class="code-snippet__selector-tag">X13</span></span></code></pre></section><h2><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">4.4 jitCagePtr</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">JavaScriptCore/llint/LLIntData.<span class="code-snippet__function">cpp</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">void</span> <span class="code-snippet__title">initialize</span><span class="code-snippet__params">()</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> ENABLE(JIT_CAGE)</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span> (Options::useJITCage())</span></code><code><span class="code-snippet_outer">        g_jscConfig.llint.gateMap[<span class="code-snippet__keyword">static_cast</span>&lt;<span class="code-snippet__keyword">unsigned</span>&gt;(Gate::jitCagePtr)] = jitCagePtrThunk().code().taggedPtr();</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018C2A8F70</span> <span class="code-snippet__selector-tag">loc_18C2A8F70</span>                           ; <span class="code-snippet__selector-tag">CODE</span> <span class="code-snippet__selector-tag">XREF</span>: <span class="code-snippet__selector-tag">JSC</span><span class="code-snippet__selector-pseudo">::LLInt</span><span class="code-snippet__selector-pseudo">::initialize(void)+C0</span>↑<span class="code-snippet__selector-tag">j</span></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018C2A8F70</span>                 <span class="code-snippet__selector-tag">ADRL</span>            <span class="code-snippet__selector-tag">X9</span>, <span class="code-snippet__selector-tag">unk_1D95A1030</span></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018C2A8F78</span>                 <span class="code-snippet__selector-tag">LDP</span>             <span class="code-snippet__selector-tag">X8</span>, <span class="code-snippet__selector-tag">X0</span>, <span class="code-snippet__selector-attr">[X9]</span> ; <span class="code-snippet__selector-tag">this</span></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018C2A8F7C</span>                 <span class="code-snippet__selector-tag">CBZ</span>             <span class="code-snippet__selector-tag">X0</span>, <span class="code-snippet__selector-tag">loc_18C2ABEB0</span></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018C2A8F80</span>                 <span class="code-snippet__selector-tag">MOV</span>             <span class="code-snippet__selector-tag">W9</span>, <span class="code-snippet__selector-id">#1</span></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018C2A8F84</span>                 <span class="code-snippet__selector-tag">LDADDAL</span>         <span class="code-snippet__selector-tag">W9</span>, <span class="code-snippet__selector-tag">W10</span>, <span class="code-snippet__selector-attr">[X0]</span></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018C2A8F88</span>                 <span class="code-snippet__selector-tag">STR</span>             <span class="code-snippet__selector-tag">X8</span>, <span class="code-snippet__selector-attr">[X19,#(qword_1D9598BC0 - 0x1D9598000)]</span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">    static_cast&lt;unsigned&gt;(Gate::jitCagePtr)]</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">对应</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">#(qword_1D9598BC0 - 0x1D9598000)</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">，它是将</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">unk_1D95A1030</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">内存处写入。而</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">unk_1D95A1030</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">保存的值是另一个函数设置的：</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="php"><code><span class="code-snippet_outer">__text:<span class="code-snippet__number">000000018</span>C2E03C8 __ZNSt3__117__call_once_proxyINS_5tupleIJOZN3JSC5LLInt15jitCagePtrThunkEvE4$_32EEEEEvPv</span></code><code><span class="code-snippet_outer">__text:<span class="code-snippet__number">000000018</span>C2E03C8                                         ; DATA XREF: JSC::LLInt::initialize(void)+DC↑o</span></code><code><span class="code-snippet_outer">ext:<span class="code-snippet__number">000000018</span>C2E0528                 MOV             W1, <span class="code-snippet__comment">#0xDAC10420</span></span></code><code><span class="code-snippet_outer">__text:<span class="code-snippet__number">000000018</span>C2E0530                 BL              __ZN3JSC15AssemblerBuffer20putIntegralUncheckedIiEEvT_ ; JSC::AssemblerBuffer::putIntegralUnchecked&lt;int&gt;(int)</span></code><code><span class="code-snippet_outer">__text:<span class="code-snippet__number">000000018</span>C2E0534                 ADRL            X16, _jitCagePtrGateAfter</span></code><code><span class="code-snippet_outer">__text:<span class="code-snippet__number">000000018</span>C2E053C                 PACIZA          X16</span></code><code><span class="code-snippet_outer">__text:<span class="code-snippet__number">000000018</span>C2E0540                 MOV             X0, X16</span></code><code><span class="code-snippet_outer">__text:<span class="code-snippet__number">000000018</span>C2E0544                 BL              __ZN3WTF12retagCodePtrIPvLNS_6PtrTagE1ELS2_45961EPFvvEvEET_T2_ ; WTF::retagCodePtr&lt;void *,(WTF::PtrTag)<span class="code-snippet__number">1</span>,(WTF::PtrTag)<span class="code-snippet__number">45961</span>,void (*)(void),void&gt;(void (*)(void))</span></code><code><span class="code-snippet_outer">__text:<span class="code-snippet__number">000000018</span>C2E0548                 MOV             X1, X0  ; this</span></code><code><span class="code-snippet_outer">__text:<span class="code-snippet__number">000000018</span>C2E054C                 ADD             X0, SP, <span class="code-snippet__comment">#0x3B0+var_218 ; int</span></span></code><code><span class="code-snippet_outer">__text:<span class="code-snippet__number">000000018</span>C2E0550                 MOV             W2, <span class="code-snippet__comment">#1</span></span></code><code><span class="code-snippet_outer">__text:<span class="code-snippet__number">000000018</span>C2E0554                 BL              __ZN3JSC19MacroAssemblerARM6412moveInternalINS_22AbstractMacroAssemblerINS_15ARM64EAssemblerEE13TrustedImmPtrElEEvT_NS_14ARM64Registers10RegisterIDE ; JSC::MacroAssemblerARM64::moveInternal&lt;JSC::AbstractMacroAssembler&lt;JSC::ARM64EAssembler&gt;::TrustedImmPtr,long&gt;(JSC::AbstractMacroAssembler&lt;JSC::ARM64EAssembler&gt;::TrustedImmPtr,JSC::ARM64Registers::RegisterID)</span></code><code><span class="code-snippet_outer">__text:<span class="code-snippet__number">000000018</span>C2E0558                 ADD             X0, SP, <span class="code-snippet__comment">#0x3B0+var_218</span></span></code><code><span class="code-snippet_outer">__text:<span class="code-snippet__number">000000018</span>C2E055C                 MOV             W1, <span class="code-snippet__comment">#1</span></span></code><code><span class="code-snippet_outer">__text:<span class="code-snippet__number">000000018</span>C2E0560                 MOV             W2, <span class="code-snippet__comment">#0xB389</span></span></code><code><span class="code-snippet_outer">__text:<span class="code-snippet__number">000000018</span>C2E0564                 BL              __ZN3JSC20MacroAssemblerARM64E7farJumpENS_14ARM64Registers10RegisterIDEN3WTF6PtrTagE ;</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">    unk_1D95A1030</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">内存处填充的是一段</span><span style="font-family:Calibri;">machine code</span><span style="font-family:宋体;">，大致类似：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li></ul><pre class="code-snippet__js" data-lang="properties"><code><span class="code-snippet_outer"><span class="code-snippet__attr">Mov</span> <span class="code-snippet__string">xx, jitCagePtrGateAfter</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">Brab</span> <span class="code-snippet__string">xx, 0xB389</span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">  0xB389</span><span style="font-family:宋体;">使用上一小节介绍的技术限制了它的取值范围，然后校验</span><span style="font-family:Calibri;">jitCagePtrGateAfter</span><span style="font-family:宋体;">指针并跳转到此处去执行。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">__text:<span class="code-snippet__number">000000018B</span>991A84 _jitCagePtrGateAfter                    ; DATA XREF: <span class="code-snippet__built_in">std</span>::__call_once_proxy&lt;<span class="code-snippet__built_in">std</span>::tuple&lt;JSC::LLInt::jitCagePtrThunk(<span class="code-snippet__keyword">void</span>)::$_32 &amp;&amp;&gt;&gt;(<span class="code-snippet__keyword">void</span> *)+<span class="code-snippet__number">16</span>C↓o</span></code><code><span class="code-snippet_outer">__text:<span class="code-snippet__number">000000018B</span>991A84                 RETAB</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  使用</span><span style="font-family:Calibri;">b key</span><span style="font-family:宋体;">验证栈中的返回地址。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  接下来看下</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">jitCagePtr</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018B991A68</span>                 <span class="code-snippet__selector-tag">EXPORT</span> _<span class="code-snippet__selector-tag">jitCagePtr</span></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018B991A68</span> _<span class="code-snippet__selector-tag">jitCagePtr</span>                             ; <span class="code-snippet__selector-tag">CODE</span> <span class="code-snippet__selector-tag">XREF</span>: <span class="code-snippet__selector-tag">JSC</span><span class="code-snippet__selector-pseudo">::LinkBuffer</span><span class="code-snippet__selector-pseudo">::getLinkerAddress</span>&lt;(<span class="code-snippet__selector-tag">WTF</span><span class="code-snippet__selector-pseudo">::PtrTag)47720</span>,<span class="code-snippet__selector-tag">JSC</span><span class="code-snippet__selector-pseudo">::AssemblerLabel</span>&gt;(<span class="code-snippet__selector-tag">JSC</span><span class="code-snippet__selector-pseudo">::AssemblerLabel)+A0</span>↑<span class="code-snippet__selector-tag">p</span></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018B991A68</span>                                         ; <span class="code-snippet__selector-tag">JSC</span><span class="code-snippet__selector-pseudo">::LinkBuffer</span><span class="code-snippet__selector-pseudo">::getLinkerAddress</span>&lt;(<span class="code-snippet__selector-tag">WTF</span><span class="code-snippet__selector-pseudo">::PtrTag)47720</span>,<span class="code-snippet__selector-tag">JSC</span><span class="code-snippet__selector-pseudo">::AssemblerLabel</span>&gt;(<span class="code-snippet__selector-tag">JSC</span><span class="code-snippet__selector-pseudo">::AssemblerLabel)+C4</span>↑<span class="code-snippet__selector-tag">p</span> ...</span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018B991A68</span>                 <span class="code-snippet__selector-tag">PACIBSP</span></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018B991A6C</span>                 <span class="code-snippet__selector-tag">ADRL</span>            <span class="code-snippet__selector-tag">X2</span>, _<span class="code-snippet__selector-tag">g_config</span></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018B991A74</span>                 <span class="code-snippet__selector-tag">ADD</span>             <span class="code-snippet__selector-tag">X2</span>, <span class="code-snippet__selector-tag">X2</span>, <span class="code-snippet__selector-id">#0xBC0</span></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018B991A78</span>                 <span class="code-snippet__selector-tag">MOV</span>             <span class="code-snippet__selector-tag">X13</span>, <span class="code-snippet__selector-id">#0xE016</span></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018B991A7C</span>                 <span class="code-snippet__selector-tag">LDR</span>             <span class="code-snippet__selector-tag">X17</span>, <span class="code-snippet__selector-attr">[X2]</span></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018B991A80</span>                 <span class="code-snippet__selector-tag">BRAB</span>            <span class="code-snippet__selector-tag">X17</span>, <span class="code-snippet__selector-tag">X13</span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    JitCagePtr</span><span style="font-family:宋体;">函数作为一个跳板函数，</span><span style="font-family:Calibri;">g_config[0xBC0]</span><span style="font-family:宋体;">处的函数地址已经在前面被赋值过了，然后使用</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">#0xE016</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">作为</span><span style="font-family:Calibri;">brab</span><span style="font-family:宋体;">的第一个参数，在前一小节已经介绍过了。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    Jsc</span><span style="font-family:宋体;">中有很多地方调用了</span><span style="font-family:Calibri;">jitCagePtr</span><span style="font-family:宋体;">：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100000182" data-ratio="0.7722222222222223" data-s="300,640" style="" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=70f60884&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_png%2F4iaJia7Cvd3PAdGIVfY8GSJW730JBFkrv8sCadkcq1WF8VW1ea2iaQMGjB7VcA45ibDx0Y1icey59PDlibImZiazys2lQ%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018C839068</span>                 <span class="code-snippet__selector-tag">MOV</span>             <span class="code-snippet__selector-tag">X21</span>, <span class="code-snippet__selector-tag">X22</span></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018C83906C</span>                 <span class="code-snippet__selector-tag">XPACI</span>           <span class="code-snippet__selector-tag">X21</span></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018C839070</span>                 <span class="code-snippet__selector-tag">MOV</span>             <span class="code-snippet__selector-tag">X0</span>, <span class="code-snippet__selector-tag">X21</span></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018C839074</span>                 <span class="code-snippet__selector-tag">MOV</span>             <span class="code-snippet__selector-tag">W1</span>, <span class="code-snippet__selector-id">#0x24AD</span></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018C839078</span>                 <span class="code-snippet__selector-tag">BL</span>              _<span class="code-snippet__selector-tag">jitCagePtr</span></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018C83907C</span>                 <span class="code-snippet__selector-tag">CMP</span>             <span class="code-snippet__selector-tag">X0</span>, <span class="code-snippet__selector-tag">X22</span></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018C839080</span>                 <span class="code-snippet__selector-tag">B</span><span class="code-snippet__selector-class">.NE</span>            <span class="code-snippet__selector-tag">loc_18C8392F4</span></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__selector-tag">text</span><span class="code-snippet__selector-pseudo">:000000018C839084</span>                 <span class="code-snippet__selector-tag">CBNZ</span>            <span class="code-snippet__selector-tag">X21</span>, <span class="code-snippet__selector-tag">loc_18C8390C0</span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    X22</span><span style="font-family:宋体;">为即将调用的某个函数指针，首先使用</span><span style="font-family:Calibri;">xpaci</span><span style="font-family:宋体;">清除掉它的</span><span style="font-family:Calibri;">pac code</span><span style="font-family:宋体;">，将其传入</span><span style="font-family:Calibri;">x0</span><span style="font-family:宋体;">，</span><span style="font-family:Calibri;">x1</span><span style="font-family:宋体;">传入</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">#0x24AD</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">，不同的函数可以传递不同的值，在前面讲过，</span><span style="font-family:Calibri;">brab</span><span style="font-family:宋体;">时会用到这个值校验它的完整性。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h1><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;"><span style="font-family:Calibri;">5 Isolate Heap</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;"><o:p></o:p></span></strong></h1><h2><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">5.1 </span><span style="font-family:黑体;">简述</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:Arial;mso-fareast-font-family:黑体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    GigaCage</span><span style="font-family:宋体;">解决了</span><span style="font-family:Calibri;">OOB(out of bounds)</span><span style="font-family:宋体;">的问题， 同样在</span><span style="font-family:Calibri;">bmalloc</span><span style="font-family:宋体;">里实现了一个叫做</span><span style="font-family:Calibri;">IsoHeap(Isolate heap)</span><span style="font-family:宋体;">的功能，它使每个类型的数据结构都在同一个类型的内存区域分配，形成一个类似隔离区的功能，这使得</span><span style="font-family:Calibri;">UAF(Use After Free)</span><span style="font-family:宋体;">的利用变得非常困难。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  在</span><span style="font-family:Calibri;">wtf</span><span style="font-family:宋体;">中有如何宏定义：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="ruby"><code><span class="code-snippet_outer">WTF/wtf/IsoMallocInlines.h</span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">#include &lt;bmalloc/IsoHeapInlines.h&gt;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">#define WTF_MAKE_ISO_ALLOCATED_INLINE(name) MAKE_BISO_MALLOCED_INLINE(name)</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">#define WTF_MAKE_ISO_ALLOCATED_IMPL(name) MAKE_BISO_MALLOCED_IMPL(name)</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">#define WTF_MAKE_ISO_ALLOCATED_IMPL_TEMPLATE(name) MAKE_BISO_MALLOCED_IMPL_TEMPLATE(name)</span></span></code><code><span class="code-snippet_outer">WTF_MAKE_ISO_ALLOCATED_IMPL包装了MAKE_BISO_MALLOCED_IMPL宏：</span></code><code><span class="code-snippet_outer">bmalloc/bmalloc/IsoHeapInlines.h</span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">#define MAKE_BISO_MALLOCED_IMPL(isoType) \</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__symbol">:</span><span class="code-snippet__symbol">:bmalloc</span><span class="code-snippet__symbol">:</span><span class="code-snippet__symbol">:api</span><span class="code-snippet__symbol">:</span><span class="code-snippet__symbol">:IsoHeap&lt;isoType&gt;&amp;</span> isoType::bisoHeap() \</span></code><code><span class="code-snippet_outer">{ \</span></code><code><span class="code-snippet_outer">    static <span class="code-snippet__symbol">:</span><span class="code-snippet__symbol">:bmalloc</span><span class="code-snippet__symbol">:</span><span class="code-snippet__symbol">:api</span><span class="code-snippet__symbol">:</span><span class="code-snippet__symbol">:IsoHeap&lt;isoType&gt;</span> heap(<span class="code-snippet__string">&#34;WebKit &#34;</span><span class="code-snippet__comment">#isoType); \</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">return</span> heap; \</span></code><code><span class="code-snippet_outer">} \</span></code><code><span class="code-snippet_outer">\</span></code><code><span class="code-snippet_outer">void* isoType::operator new(size_t size) \</span></code><code><span class="code-snippet_outer">{ \</span></code><code><span class="code-snippet_outer">    RELEASE_BASSERT(size == sizeof(isoType)); \</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">return</span> bisoHeap().allocate(); \</span></code><code><span class="code-snippet_outer">} \</span></code><code><span class="code-snippet_outer">\</span></code><code><span class="code-snippet_outer">void isoType::operator delete(void* p) \</span></code><code><span class="code-snippet_outer">{ \</span></code><code><span class="code-snippet_outer">    bisoHeap().deallocate(p); \</span></code><code><span class="code-snippet_outer">} \</span></code><code><span class="code-snippet_outer">\</span></code><code><span class="code-snippet_outer">void isoType::freeAfterDestruction(void* p) \</span></code><code><span class="code-snippet_outer">{ \</span></code><code><span class="code-snippet_outer">    bisoHeap().deallocate(p); \</span></code><code><span class="code-snippet_outer">} \</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">    IsoHeap</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">模板根据不同的类型生成了一些函数，比如重载了</span><span style="font-family:Calibri;">new</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">delete</span><span style="font-family:宋体;">运算符，当对这个类型的数据进行</span><span style="font-family:Calibri;">new</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">delete</span><span style="font-family:宋体;">时，就会使用</span><span style="font-family:Calibri;">IsoHeap</span><span style="font-family:宋体;">的接口。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;"> 在</span><span style="font-family:Calibri;">webkit</span><span style="font-family:宋体;">的代码中，存在大量的使用</span><span style="font-family:Calibri;">IsoHeap</span><span style="font-family:宋体;">的代码，比如：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">WebCore/rendering/RenderTableRow.<span class="code-snippet__function">cpp</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer"><span class="code-snippet__title">WTF_MAKE_ISO_ALLOCATED_IMPL</span><span class="code-snippet__params">(RenderTableRow)</span></span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">RenderTableRow::RenderTableRow(Element&amp; element, RenderStyle&amp;&amp; style)</span></code><code><span class="code-snippet_outer">    : RenderBox(element, WTFMove(style), <span class="code-snippet__number">0</span>)</span></code><code><span class="code-snippet_outer">    , m_rowIndex(unsetRowIndex)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">    setInline(<span class="code-snippet__literal">false</span>);</span></code><code><span class="code-snippet_outer">    setIsTableRow();</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">RenderTableRow::RenderTableRow(Document&amp; document, RenderStyle&amp;&amp; style)</span></code><code><span class="code-snippet_outer">    : RenderBox(document, WTFMove(style), <span class="code-snippet__number">0</span>)</span></code><code><span class="code-snippet_outer">    , m_rowIndex(unsetRowIndex)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">    setInline(<span class="code-snippet__literal">false</span>);</span></code><code><span class="code-snippet_outer">    setIsTableRow();</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><h2><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">5.2 </span><span style="font-family:黑体;">实现</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    IsoHeap</span><span style="font-family:宋体;">定义了一个名为</span><span style="font-family:Calibri;">Directory</span><span style="font-family:宋体;">的内存块，它包含若干</span><span style="font-family:Calibri;">Page</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">bmalloc/bmalloc/IsoDirectory.h</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">template</span>&lt;<span class="code-snippet__keyword">typename</span> Config, <span class="code-snippet__keyword">unsigned</span> passedNumPages&gt;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">IsoDirectory</span> :</span> <span class="code-snippet__keyword">public</span> IsoDirectoryBase&lt;Config&gt; {</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span>:</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">constexpr</span> <span class="code-snippet__keyword">unsigned</span> numPages = passedNumPages;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">private</span>:</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">void</span> <span class="code-snippet__title">scavengePage</span><span class="code-snippet__params">(<span class="code-snippet__keyword">const</span> LockHolder&amp;, <span class="code-snippet__keyword">size_t</span>, Vector&lt;DeferredDecommit&gt;&amp;)</span></span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__built_in">std</span>::<span class="code-snippet__built_in">array</span>&lt;PackedAlignedPtr&lt;IsoPage&lt;Config&gt;, IsoPage&lt;Config&gt;::pageSize&gt;, numPages&gt; m_pages { };</span></code><code><span class="code-snippet_outer">    Bits&lt;numPages&gt; m_eligible;</span></code><code><span class="code-snippet_outer">    Bits&lt;numPages&gt; m_empty;</span></code><code><span class="code-snippet_outer">Bits&lt;numPages&gt; m_committed;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  这些</span><span style="font-family:Calibri;">Directory</span><span style="font-family:宋体;">内存块通过单链表链接起来。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">bmalloc/bmalloc/IsoHeapImplInlines.h</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">template</span>&lt;<span class="code-snippet__keyword">typename</span> Config&gt;</span></code><code><span class="code-snippet_outer">EligibilityResult&lt;Config&gt; IsoHeapImpl&lt;Config&gt;::takeFirstEligible(<span class="code-snippet__keyword">const</span> LockHolder&amp; locker)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">auto</span>* newDirectory = <span class="code-snippet__keyword">new</span> IsoDirectoryPage&lt;Config&gt;(*<span class="code-snippet__keyword">this</span>, m_nextDirectoryPageIndex++);</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span> (m_headDirectory.get()) {</span></code><code><span class="code-snippet_outer">        m_tailDirectory-&gt;next = newDirectory;</span></code><code><span class="code-snippet_outer">        m_tailDirectory = newDirectory;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  每个</span><span style="font-family:Calibri;">Page</span><span style="font-family:宋体;">包含若干</span><span style="font-family:Calibri;">chunk</span><span style="font-family:宋体;">，</span><span style="font-family:Calibri;">chunk</span><span style="font-family:宋体;">大小由</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">Config::objectSize</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">定义。</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">bmalloc/bmalloc/IsoPage.h</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">template</span>&lt;<span class="code-snippet__keyword">typename</span> Config&gt;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">IsoPage</span> :</span> <span class="code-snippet__keyword">public</span> IsoPageBase {</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span>:</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">constexpr</span> <span class="code-snippet__keyword">unsigned</span> numObjects = pageSize / Config::objectSize;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__title">index</span><span class="code-snippet__params">()</span> <span class="code-snippet__keyword">const</span> </span>{ <span class="code-snippet__keyword">return</span> m_index; }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">void</span> <span class="code-snippet__title">free</span><span class="code-snippet__params">(<span class="code-snippet__keyword">const</span> LockHolder&amp;, <span class="code-snippet__keyword">void</span>*)</span></span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__comment">// Called after this page is already selected for allocation.</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function">FreeList <span class="code-snippet__title">startAllocating</span><span class="code-snippet__params">(<span class="code-snippet__keyword">const</span> LockHolder&amp;)</span></span>;</span></code><code><span class="code-snippet_outer">    DeferredTrigger&lt;IsoPageTrigger::Eligible&gt; m_eligibilityTrigger;</span></code><code><span class="code-snippet_outer">    DeferredTrigger&lt;IsoPageTrigger::Empty&gt; m_emptyTrigger;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">uint8_t</span> m_numNonEmptyWords { <span class="code-snippet__number">0</span> };</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">static_assert</span>(bitsArrayLength(numObjects) &lt;= UINT8_MAX);</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">unsigned</span> m_index { UINT_MAX };</span></code><code><span class="code-snippet_outer">    IsoDirectoryBase&lt;Config&gt;&amp; m_directory;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">unsigned</span> m_allocBits[bitsArrayLength(numObjects)];</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  每个</span><span style="font-family:Calibri;">page</span><span style="font-family:宋体;">的状态由如下定义：空、全满、半满，这跟</span><span style="font-family:Calibri;">slab</span><span style="font-family:宋体;">的算法类似，内存分配器算法也就那么几种。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    Page</span><span style="font-family:宋体;">中的每个</span><span style="font-family:Calibri;">chunk</span><span style="font-family:宋体;">放到一个叫做</span><span style="font-family:Calibri;">Freelist</span><span style="font-family:宋体;">的链表中：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">bmalloc/bmalloc/FreeList.h</span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">FreeList</span> {</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span>:</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function">BEXPORT <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">initializeList</span><span class="code-snippet__params">(FreeCell* head, <span class="code-snippet__keyword">uintptr_t</span> secret, <span class="code-snippet__keyword">unsigned</span> bytes)</span></span>;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function">BEXPORT <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">initializeBump</span><span class="code-snippet__params">(<span class="code-snippet__keyword">char</span>* payloadEnd, <span class="code-snippet__keyword">unsigned</span> remaining)</span></span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">private</span>:</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function">FreeCell* <span class="code-snippet__title">head</span><span class="code-snippet__params">()</span> <span class="code-snippet__keyword">const</span> </span>{ <span class="code-snippet__keyword">return</span> FreeCell::descramble(m_scrambledHead, m_secret); }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">uintptr_t</span> m_scrambledHead { <span class="code-snippet__number">0</span> };</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">uintptr_t</span> m_secret { <span class="code-snippet__number">0</span> };</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    FreeList</span><span style="font-family:宋体;">中的每个节点指向的下一个节点地址都做了混淆保护：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">FreeCell</span> {</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">static</span> uintptr_t <span class="code-snippet__title">scramble</span><span class="code-snippet__params">(FreeCell* cell, <span class="code-snippet__keyword">uintptr_t</span> secret)</span></span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> <span class="code-snippet__keyword">reinterpret_cast</span>&lt;<span class="code-snippet__keyword">uintptr_t</span>&gt;(cell) ^ secret;</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">static</span> FreeCell* <span class="code-snippet__title">descramble</span><span class="code-snippet__params">(<span class="code-snippet__keyword">uintptr_t</span> cell, <span class="code-snippet__keyword">uintptr_t</span> secret)</span></span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> <span class="code-snippet__keyword">reinterpret_cast</span>&lt;FreeCell*&gt;(cell ^ secret);</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">void</span> <span class="code-snippet__title">setNext</span><span class="code-snippet__params">(FreeCell* next, <span class="code-snippet__keyword">uintptr_t</span> secret)</span></span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        scrambledNext = scramble(next, secret);</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function">FreeCell* <span class="code-snippet__title">next</span><span class="code-snippet__params">(<span class="code-snippet__keyword">uintptr_t</span> secret)</span> <span class="code-snippet__keyword">const</span></span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> descramble(scrambledNext, secret);</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">uintptr_t</span> scrambledNext;</span></code><code><span class="code-snippet_outer">};</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">    secret</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">是一个运行时产生的随机数。</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">bmalloc/bmalloc/IsoPageInlines.h</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">template</span>&lt;<span class="code-snippet__keyword">typename</span> Config&gt;</span></code><code><span class="code-snippet_outer">FreeList IsoPage&lt;Config&gt;::startAllocating(<span class="code-snippet__keyword">const</span> LockHolder&amp;)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">uintptr_t</span> secret;</span></code><code><span class="code-snippet_outer">cryptoRandom(&amp;secret, <span class="code-snippet__keyword">sizeof</span>(secret));</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"> 产生一个随机数。</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">    FreeCell* head = <span class="code-snippet__literal">nullptr</span>;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">unsigned</span> bytes = <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">for</span> (<span class="code-snippet__keyword">unsigned</span> index = indexOfFirstObject(); index &lt; numObjects; ++index) {</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsigned</span> wordIndex = index &gt;&gt; <span class="code-snippet__number">5</span>;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsigned</span> word = m_allocBits[wordIndex];</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsigned</span> bitMask = <span class="code-snippet__number">1</span> &lt;&lt; (index &amp; <span class="code-snippet__number">31</span>);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (word &amp; bitMask)</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">continue</span>;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (!word)</span></code><code><span class="code-snippet_outer">            m_numNonEmptyWords++;</span></code><code><span class="code-snippet_outer">        m_allocBits[wordIndex] = word | bitMask;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">char</span>* cellByte = <span class="code-snippet__keyword">reinterpret_cast</span>&lt;<span class="code-snippet__keyword">char</span>*&gt;(<span class="code-snippet__keyword">this</span>) + index * Config::objectSize;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (verbose)</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__built_in">fprintf</span>(<span class="code-snippet__built_in">stderr</span>, <span class="code-snippet__string">&#34;%p: putting %p on free list.\n&#34;</span>, <span class="code-snippet__keyword">this</span>, cellByte);</span></code><code><span class="code-snippet_outer">        FreeCell* cell = bitwise_cast&lt;FreeCell*&gt;(cellByte);</span></code><code><span class="code-snippet_outer">        cell-&gt;setNext(head, secret);</span></code></pre></section><p style="margin-left: 21pt;"><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">下一个</span><span style="font-family:Calibri;">cell</span><span style="font-family:宋体;">的地址加密存储。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="nginx"><code><span class="code-snippet_outer">      <span class="code-snippet__attribute">head</span> = cell;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__attribute">bytes</span> += Config::objectSize;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style="margin-left: 21pt;"><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">我们看到虽然</span><span style="font-family:Calibri;">cell</span><span style="font-family:宋体;">的地址使用了加密存储，但是每个</span><span style="font-family:Calibri;">cell</span><span style="font-family:宋体;">在初始化时是顺序存储的，没有像</span><span style="font-family:Calibri;">linux slub</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">ios zone</span><span style="font-family:宋体;">一样使用洗牌算法将</span><span style="font-family:Calibri;">cell</span><span style="font-family:宋体;">顺序打乱。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h1><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;"><span style="font-family:Calibri;">6 StructureID Protection</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;"><o:p></o:p></span></strong></h1><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    webkit</span><span style="font-family:宋体;">在</span><span style="font-family:Calibri;">2019</span><span style="font-family:宋体;">年时使用随机化技术对</span><span style="font-family:Calibri;">StructureID</span><span style="font-family:宋体;">进行了保护：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100000183" data-ratio="0.15833333333333333" data-s="300,640" style="" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=c8ba8747&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_png%2F4iaJia7Cvd3PAdGIVfY8GSJW730JBFkrv8oawdvVic94uicE14y9rvlRSIhyVdPdTCibNHcXcj8TRMTT8YBBtmTx3Og%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/><span style="font-family: Calibri;font-size: 10.5pt;letter-spacing: 0.034em;text-align: justify;"></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  即使使用了随机化，由于</span><span style="font-family:Calibri;">entropy bits</span><span style="font-family:宋体;">较少，已经出现很多绕过方法，因此</span><span style="font-family:Calibri;">webkit</span><span style="font-family:宋体;">在最新的版本中去掉了随机化功能，使用了新的保护技术。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">JavaScriptCore/runtime/StructureID.h</span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">StructureID</span> {</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span>:</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">constexpr</span> <span class="code-snippet__keyword">uint32_t</span> nukedStructureIDBit = <span class="code-snippet__number">1</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> ENABLE(STRUCTURE_ID_WITH_SHIFT)</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">constexpr</span> <span class="code-snippet__keyword">unsigned</span> encodeShiftAmount = <span class="code-snippet__number">4</span>;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">elif</span> CPU(ADDRESS64)</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">constexpr</span> CPURegister structureIDMask = structureHeapAddressSize - <span class="code-snippet__number">1</span>;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  最低位还是一个</span><span style="font-family:Calibri;">bit</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">Nuke Bit</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">     STRUCTURE_ID_WITH_SHIFT</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">宏用在</span><span style="font-family:Calibri;">64bit</span><span style="font-family:宋体;">地址，但是</span><span style="font-family:Calibri;">cpu</span><span style="font-family:宋体;">仅使用了</span><span style="font-family:Calibri;">36bit</span><span style="font-family:宋体;">有效地址的情景下，它将</span><span style="font-family:Calibri;">StructureID</span><span style="font-family:宋体;">的地址进行移位编码存储。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> ENABLE(STRUCTURE_ID_WITH_SHIFT)</span></span></code><code><span class="code-snippet_outer">ALWAYS_INLINE StructureID StructureID::encode(<span class="code-snippet__keyword">const</span> Structure* structure)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">    ASSERT(structure);</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">auto</span> result = StructureID(<span class="code-snippet__keyword">reinterpret_cast</span>&lt;<span class="code-snippet__keyword">uintptr_t</span>&gt;(structure) &gt;&gt; encodeShiftAmount);</span></code><code><span class="code-snippet_outer">    ASSERT(result.decode() == structure);</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">return</span> result;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  编码时右移了</span><span style="font-family:Calibri;">4</span><span style="font-family:宋体;">位，因此它只能编码</span><span style="font-family:Calibri;">36bit</span><span style="font-family:宋体;">的内存地址。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">ALWAYS_INLINE Structure* StructureID::decode() <span class="code-snippet__keyword">const</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">    ASSERT(decontaminate());</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">return</span> <span class="code-snippet__keyword">reinterpret_cast</span>&lt;Structure*&gt;(<span class="code-snippet__keyword">static_cast</span>&lt;<span class="code-snippet__keyword">uintptr_t</span>&gt;(decontaminate().m_bits) &lt;&lt; encodeShiftAmount);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  解码时在左移</span><span style="font-family:Calibri;">4</span><span style="font-family:宋体;">位。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  如果</span><span style="font-family:Calibri;">cpu</span><span style="font-family:宋体;">使用更大的寻址能力，</span><span style="font-family:Calibri;">webkit</span><span style="font-family:宋体;">使用以下编码方式：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">elif</span> CPU(ADDRESS64)</span></span></code><code><span class="code-snippet_outer">ALWAYS_INLINE StructureID StructureID::encode(<span class="code-snippet__keyword">const</span> Structure* structure)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">    ASSERT(structure);</span></code><code><span class="code-snippet_outer">    ASSERT(g_jscConfig.startOfStructureHeap &lt;= <span class="code-snippet__keyword">reinterpret_cast</span>&lt;<span class="code-snippet__keyword">uintptr_t</span>&gt;(structure) &amp;&amp; <span class="code-snippet__keyword">reinterpret_cast</span>&lt;<span class="code-snippet__keyword">uintptr_t</span>&gt;(structure) &lt; g_jscConfig.startOfStructureHeap + structureHeapAddressSize);</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">auto</span> result = StructureID(<span class="code-snippet__keyword">reinterpret_cast</span>&lt;<span class="code-snippet__keyword">uintptr_t</span>&gt;(structure) &amp; structureIDMask);</span></code><code><span class="code-snippet_outer">    ASSERT(result.decode() == structure);</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">return</span> result;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  编码时使用</span><span style="font-family:Calibri;">structure</span><span style="font-family:宋体;">的地址与上</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">structureIDMask</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">, </span><span style="font-family:宋体;">然后调用</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">StructureID</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">构造函数对</span><span style="font-family:Calibri;">m_bits</span><span style="font-family:宋体;">进行赋值，它是</span><span style="font-family:Calibri;">32bit</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">StructureID</span> {</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span>:</span></code><code><span class="code-snippet_outer">   <span class="code-snippet__keyword">static</span> constexpr uint32_t nukedStructureIDBit = <span class="code-snippet__number">1</span>;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">private</span>:</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">explicit</span> <span class="code-snippet__title">StructureID</span>(<span class="code-snippet__params">uint32_t bits</span>) : <span class="code-snippet__title">m_bits</span>(<span class="code-snippet__params">bits</span>)</span> { }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    uint32_t m_bits { <span class="code-snippet__number">0</span> };</span></code><code><span class="code-snippet_outer">};</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">    structureIDMask</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">可以选取以下值：</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> defined(STRUCTURE_HEAP_ADDRESS_SIZE_IN_MB) &amp;&amp; STRUCTURE_HEAP_ADDRESS_SIZE_IN_MB &gt; 0</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">constexpr</span> <span class="code-snippet__keyword">uintptr_t</span> structureHeapAddressSize = STRUCTURE_HEAP_ADDRESS_SIZE_IN_MB * MB;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">elif</span> PLATFORM(PLAYSTATION)</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">constexpr</span> <span class="code-snippet__keyword">uintptr_t</span> structureHeapAddressSize = <span class="code-snippet__number">128</span> * MB;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">elif</span> PLATFORM(IOS_FAMILY) &amp;&amp; CPU(ARM64) &amp;&amp; !CPU(ARM64E)</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">constexpr</span> <span class="code-snippet__keyword">uintptr_t</span> structureHeapAddressSize = <span class="code-snippet__number">512</span> * MB;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">else</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">constexpr</span> <span class="code-snippet__keyword">uintptr_t</span> structureHeapAddressSize = <span class="code-snippet__number">4</span> * GB;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">constexpr</span> CPURegister structureIDMask = structureHeapAddressSize - <span class="code-snippet__number">1</span>;</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  可以看到如果</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">structureHeapAddressSize</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">为</span><span style="font-family:Calibri;">4G</span><span style="font-family:宋体;">，</span><span style="font-family:Calibri;">m_bits</span><span style="font-family:宋体;">可以代表全部的</span><span style="font-family:Calibri;">32bit</span><span style="font-family:宋体;">，它是一个在</span><span style="font-family:Calibri;">StructureHeap</span><span style="font-family:宋体;">的索引，这使得猜测</span><span style="font-family:Calibri;">StructureID</span><span style="font-family:宋体;">的值比随机化</span><span style="font-family:Calibri;">5bit</span><span style="font-family:宋体;">更加困难。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">ALWAYS_INLINE Structure* StructureID::decode() <span class="code-snippet__keyword">const</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__comment">// Take care to only use the bits from m_bits in the structure&#39;s address reservation.</span></span></code><code><span class="code-snippet_outer">    ASSERT(decontaminate());</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">return</span> <span class="code-snippet__keyword">reinterpret_cast</span>&lt;Structure*&gt;((<span class="code-snippet__keyword">static_cast</span>&lt;<span class="code-snippet__keyword">uintptr_t</span>&gt;(decontaminate().m_bits) &amp; structureIDMask) + g_jscConfig.startOfStructureHeap);</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;"> 解码时</span><span style="font-family:Calibri;">m_bits</span><span style="font-family:宋体;">在与上</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">structureIDMask</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">, </span><span style="font-family:宋体;">它是一个</span><span style="font-family:Calibri;">32bit</span><span style="font-family:宋体;">的索引，因此要在加上</span><span style="font-family:Calibri;">sturctureID</span><span style="font-family:宋体;">的基地址</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">g_jscConfig.startOfStructureHeap</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">。</span></p><p style="display: none;"><mp-style-type data-value="3"></mp-style-type></p>



<p><a href="2247483834">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=f01d4199&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg4NjU1NDU4MA%3D%3D%26mid%3D2247483834%26idx%3D1%26sn%3D144af0c9a52a75f37834238ae0875bce%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Wed, 13 Mar 2024 20:58:00 +0800</pubDate>
    </item>
    <item>
      <title>Chrome浏览器安全之PartitionAlloc内存分配器分析</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg4NjU1NDU4MA==&amp;mid=2247483827&amp;idx=1&amp;sn=e0df8e57dba39d003d2458b83af41744</link>
      <description>PartitionAlloc内存分配器是笔者迄今为止读过的最复杂的内存分配器，大约有3w+行代码。</description>
      <content:encoded><![CDATA[<p>
原创 <span>wzt</span> <span>2024-03-11 12:11</span> <span style="display: inline-block;">上海</span>
</p>

<p>PartitionAlloc内存分配器是笔者迄今为止读过的最复杂的内存分配器，大约有3w+行代码。</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=9127ccfc&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_jpg%2F4iaJia7Cvd3PCnqCX6ZrmoQ61QHfyMzzTgmPtdMdVh2ZbY7Dv7nfJXTIUJQwrUycfc2SBamdUeuLF0onicWyLe0hA%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<p>    PartitionAlloc内存分配器是笔者迄今为止读过的最复杂的内存分配器，大约有3w+行代码。</p><h1><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;"><span style="font-family:Calibri;">1 </span><span style="font-family:宋体;">数据结构</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;"><o:p></o:p></span></strong></h1><h2 style="margin-left:0.0000pt;text-indent:0.0000pt;mso-list:l0 level2 lfo1;"><span style="font-family:Arial;mso-fareast-font-family:黑体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;">1.1 </span><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">PartitionRoot</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    PartitionRoot</span><span style="font-family:宋体;">对象是</span><span style="font-family:Calibri;">PartitionAlloc</span><span style="font-family:宋体;">内存管理总的对象入口。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">partition_allocator/partition_root.h</span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">struct <span class="code-snippet__title">PA_ALIGNAS</span><span class="code-snippet__params">(<span class="code-snippet__number">64</span>)</span> <span class="code-snippet__title">PA_COMPONENT_EXPORT</span><span class="code-snippet__params">(PARTITION_ALLOC)</span> PartitionRoot </span>{</span></code><code><span class="code-snippet_outer">  Bucket buckets[internal::kNumBuckets] = {};</span></code><code><span class="code-snippet_outer">  Bucket sentinel_bucket{};</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">uintptr_t</span> next_super_page = <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">uintptr_t</span> next_partition_page = <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">uintptr_t</span> next_partition_page_end = <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer">  SuperPageExtentEntry* current_extent = <span class="code-snippet__literal">nullptr</span>;</span></code><code><span class="code-snippet_outer">  SuperPageExtentEntry* first_extent = <span class="code-snippet__literal">nullptr</span>;</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__function">DirectMapExtent* direct_map_list <span class="code-snippet__title">PA_GUARDED_BY</span><span class="code-snippet__params">(lock_)</span> </span>= <span class="code-snippet__literal">nullptr</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">   <span class="code-snippet__function"><span class="code-snippet__keyword">void</span> <span class="code-snippet__title">Init</span><span class="code-snippet__params">(PartitionOptions)</span></span>;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    buckets</span><span style="font-family:宋体;">是个</span><span style="font-family:Calibri;">Bucket</span><span style="font-family:宋体;">类型的数组，它的每个元素代表特定的</span><span style="font-family:Calibri;">slot</span><span style="font-family:宋体;">大小。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    Init</span><span style="font-family:宋体;">函数用于初始化</span><span style="font-family:Calibri;">PartitionAddressSpace</span><span style="font-family:宋体;">以及</span><span style="font-family:Calibri;">ThreadCache</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h2 style="margin-left:0.0000pt;text-indent:0.0000pt;mso-list:l0 level2 lfo1;"><span style="font-family:Arial;mso-fareast-font-family:黑体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;">1.2 </span><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">PartitionAddressSpace</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">partition_allocator/partition_address_space.<span class="code-snippet__function">h</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">class <span class="code-snippet__title">PA_COMPONENT_EXPORT</span><span class="code-snippet__params">(PARTITION_ALLOC)</span> PartitionAddressSpace </span>{</span></code><code><span class="code-snippet_outer">  PA_ALWAYS_INLINE <span class="code-snippet__keyword">static</span> <span class="code-snippet__built_in">std</span>::pair&lt;pool_handle, <span class="code-snippet__keyword">uintptr_t</span>&gt; GetPoolAndOffset(</span></code><code><span class="code-snippet_outer">      <span class="code-snippet__keyword">uintptr_t</span> address)；</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">PoolSetup</span> {</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">union</span> {</span></code><code><span class="code-snippet_outer">      <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> {</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">uintptr_t</span> regular_pool_base_address_;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">uintptr_t</span> brp_pool_base_address_;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">uintptr_t</span> configurable_pool_base_address_;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> BUILDFLAG(ENABLE_PKEYS)</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">uintptr_t</span> pkey_pool_base_address_;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> PA_CONFIG(DYNAMICALLY_SELECT_POOL_SIZE)</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">uintptr_t</span> regular_pool_base_mask_;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">uintptr_t</span> brp_pool_base_mask_;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> PA_CONFIG(GLUE_CORE_POOLS)</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">uintptr_t</span> core_pools_base_mask_;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span>  <span class="code-snippet__comment">// PA_CONFIG(DYNAMICALLY_SELECT_POOL_SIZE)</span></span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">uintptr_t</span> configurable_pool_base_mask_;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> BUILDFLAG(ENABLE_PKEYS)</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">int</span> pkey_;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code><code><span class="code-snippet_outer">      };</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> BUILDFLAG(ENABLE_PKEYS)</span></span></code><code><span class="code-snippet_outer">      <span class="code-snippet__keyword">char</span> one_page_[SystemPageSize()];</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">else</span></span></span></code><code><span class="code-snippet_outer">      <span class="code-snippet__keyword">char</span> one_cacheline_[kPartitionCachelineSize];</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code><code><span class="code-snippet_outer">    };</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">static</span> PoolSetup setup_ PA_CONSTINIT;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">    setup_</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">字段保存了每个</span><span style="font-family:Calibri;">pool</span><span style="font-family:宋体;">的类型和起始地址，通过</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">GetPoolAndOffset</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">来获取。</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h2 style="margin-left:0.0000pt;mso-para-margin-left:0.0000gd;text-indent:0.0000pt;mso-char-indent-count:0.0000;mso-list:l0 level2 lfo1;"><span style="font-family:Arial;mso-fareast-font-family:黑体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;">1.3 </span><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">AddressPoolManager</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    PartitionAlloc</span><span style="font-family:宋体;">通过</span><span style="font-family:Calibri;">POOL</span><span style="font-family:宋体;">的概念管理内存池，一个进程有</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">kNumPools</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">个类型的</span><span style="font-family:Calibri;">pool</span><span style="font-family:宋体;">，注意内存池是对整个进程共有的，不是线程专有。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">enum</span> pool_handle : unsigned {</span></code><code><span class="code-snippet_outer">  kNullPoolHandle = <span class="code-snippet__number">0u</span>,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">  kRegularPoolHandle,</span></code><code><span class="code-snippet_outer">  kBRPPoolHandle,</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> BUILDFLAG(HAS_64_BIT_POINTERS)</span></span></code><code><span class="code-snippet_outer">  kConfigurablePoolHandle,</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> BUILDFLAG(ENABLE_PKEYS)</span></span></code><code><span class="code-snippet_outer">  kPkeyPoolHandle,</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code><code><span class="code-snippet_outer">  kMaxPoolHandle</span></code><code><span class="code-snippet_outer">};</span></code><code><span class="code-snippet_outer">constexpr size_t kNumPools = kMaxPoolHandle - <span class="code-snippet__number">1</span>;</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">    kBRPPoolHandle</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">用于</span><span style="font-family:Calibri;">32</span><span style="font-family:宋体;">位，</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">kPkeyPoolHandle</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">用于</span><span style="font-family:Calibri;">x86</span><span style="font-family:宋体;">提供的</span><span style="font-family:Calibri;">pkey</span><span style="font-family:宋体;">保护，</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">kRegularPoolHandle</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">和</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">kConfigurablePoolHandle</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">是我们关心的。</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    Pool</span><span style="font-family:宋体;">依附于</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">AddressPoolManager</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">结构体内：</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__function">class <span class="code-snippet__title">PA_COMPONENT_EXPORT</span><span class="code-snippet__params">(PARTITION_ALLOC)</span> AddressPoolManager </span>{</span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">Pool</span> {</span></span></code><code><span class="code-snippet_outer">   <span class="code-snippet__keyword">public</span>:</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">uintptr_t</span> address_begin_ = <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">bool</span> <span class="code-snippet__title">TryReserveChunk</span><span class="code-snippet__params">(<span class="code-snippet__keyword">uintptr_t</span> address, <span class="code-snippet__keyword">size_t</span> size)</span></span>;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> {</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">char</span> pad_[PA_PKEY_ARRAY_PAD_SZ(Pool, kNumPools)] = {};</span></code><code><span class="code-snippet_outer">    Pool pools_[kNumPools];</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">char</span> pad_after_[PA_PKEY_FILL_PAGE_SZ(<span class="code-snippet__keyword">sizeof</span>(Pool))] = {};</span></code><code><span class="code-snippet_outer">} aligned_pools_ PA_PKEY_ALIGN;</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">void</span> <span class="code-snippet__title">Add</span><span class="code-snippet__params">(pool_handle handle, <span class="code-snippet__keyword">uintptr_t</span> address, <span class="code-snippet__keyword">size_t</span> length)</span></span>;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">uintptr_t</span> Reserve(pool_handle handle, <span class="code-snippet__keyword">uintptr_t</span> requested_address, <span class="code-snippet__keyword">size_t</span> length);</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">    Reserve</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">函数通过</span><span style="font-family:Calibri;">mmap</span><span style="font-family:宋体;">为</span><span style="font-family:Calibri;">pool</span><span style="font-family:宋体;">保留一段特定大小的内存。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    Add</span><span style="font-family:宋体;">函数初始化一个</span><span style="font-family:Calibri;">pool</span><span style="font-family:宋体;">的地址。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">void</span> AddressPoolManager::Add(pool_handle handle, <span class="code-snippet__keyword">uintptr_t</span> ptr, <span class="code-snippet__keyword">size_t</span> length) {</span></code><code><span class="code-snippet_outer">  Pool* pool = GetPool(handle);</span></code><code><span class="code-snippet_outer">  PA_CHECK(!pool-&gt;IsInitialized());</span></code><code><span class="code-snippet_outer">  pool-&gt;Initialize(ptr, length);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">void</span> AddressPoolManager::Pool::Initialize(<span class="code-snippet__keyword">uintptr_t</span> ptr, <span class="code-snippet__keyword">size_t</span> length) {</span></code><code><span class="code-snippet_outer">  address_begin_ = ptr;</span></code><code><span class="code-snippet_outer">  address_end_ = ptr + length;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    Add</span><span style="font-family:宋体;">函数通过上面介绍的</span><span style="font-family:Calibri;">PartitionAddressSpace:init</span><span style="font-family:宋体;">对所有的</span><span style="font-family:Calibri;">pool</span><span style="font-family:宋体;">进行初始化赋值：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="php"><code><span class="code-snippet_outer">void PartitionAddressSpace::Init() {</span></code><code><span class="code-snippet_outer">  setup_.regular_pool_base_address_ =</span></code><code><span class="code-snippet_outer">      AllocPages(regular_pool_size, regular_pool_size,</span></code><code><span class="code-snippet_outer">                 PageAccessibilityConfiguration(</span></code><code><span class="code-snippet_outer">                     PageAccessibilityConfiguration::kInaccessible),</span></code><code><span class="code-snippet_outer">                 PageTag::kPartitionAlloc, regular_pool_fd);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">  AddressPoolManager::GetInstance().Add(</span></code><code><span class="code-snippet_outer">      kRegularPoolHandle, setup_.regular_pool_base_address_, regular_pool_size);</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><h2 style="margin-left:0.0000pt;mso-para-margin-left:0.0000gd;text-indent:0.0000pt;mso-char-indent-count:0.0000;mso-list:l0 level2 lfo1;"><span style="font-family:Arial;mso-fareast-font-family:黑体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;">1.4 </span><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:Arial;mso-fareast-font-family:黑体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;">PartitionBucket</span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:Arial;mso-fareast-font-family:黑体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">partition_allocator/partition_bucket.h</span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">PartitionBucket</span> {</span></span></code><code><span class="code-snippet_outer">  SlotSpanMetadata&lt;thread_safe&gt;* active_slot_spans_head;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">  SlotSpanMetadata&lt;thread_safe&gt;* empty_slot_spans_head;</span></code><code><span class="code-snippet_outer">  SlotSpanMetadata&lt;thread_safe&gt;* decommitted_slot_spans_head;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">uint32_t</span> num_full_slot_spans : <span class="code-snippet__number">24</span>;</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__function">PA_ALWAYS_INLINE uintptr_t <span class="code-snippet__title">AllocNewSuperPageSpan</span><span class="code-snippet__params">(</span></span></span></code><code><span class="code-snippet_outer">      PartitionRoot&lt;thread_safe&gt;* root,</span></code><code><span class="code-snippet_outer">      <span class="code-snippet__keyword">size_t</span> super_page_count,</span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">      <span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">int</span> flags)</span> <span class="code-snippet__title">PA_EXCLUSIVE_LOCKS_REQUIRED</span><span class="code-snippet__params">(root-&gt;lock_)</span>;</span></code><code><span class="code-snippet_outer">  PA_ALWAYS_INLINE SlotSpanMetadata&lt;thread_safe&gt;* AllocNewSlotSpan(</span></code><code><span class="code-snippet_outer">      PartitionRoot&lt;thread_safe&gt;* root,</span></code><code><span class="code-snippet_outer">      <span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">int</span> flags,</span></code><code><span class="code-snippet_outer">      <span class="code-snippet__keyword">size_t</span> slot_span_alignment) PA_EXCLUSIVE_LOCKS_REQUIRED(root-&gt;lock_);</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__function">PA_ALWAYS_INLINE uintptr_t <span class="code-snippet__title">AllocNewSuperPage</span><span class="code-snippet__params">(PartitionRoot&lt;thread_safe&gt;* root,</span></span></span></code><code><span class="code-snippet_outer">                                               <span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">int</span> flags)</span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">      <span class="code-snippet__title">PA_EXCLUSIVE_LOCKS_REQUIRED</span><span class="code-snippet__params">(root-&gt;lock_)</span></span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__function">PA_ALWAYS_INLINE <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">InitializeSlotSpan</span><span class="code-snippet__params">(</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">      SlotSpanMetadata&lt;thread_safe&gt;* slot_span)</span>;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  一个</span><span style="font-family:Calibri;">bucket</span><span style="font-family:宋体;">用于分配一个特定大小的内存块。</span><span style="font-family:Calibri;">Bucket</span><span style="font-family:宋体;">由一个个类型为</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">SlotSpanMetadata</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">slotspan</span><span style="font-family:宋体;">链接起来，</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">active_slot_spans_head</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">链接当前活跃的</span><span style="font-family:Calibri;">slotspan</span><span style="font-family:宋体;">，即半满状态的</span><span style="font-family:Calibri;">slotspan</span><span style="font-family:宋体;">，</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">empty_slot_spans_head</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">链接为空的</span><span style="font-family:Calibri;">slotspan</span><span style="font-family:宋体;">，</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">decommitted_slot_spans_head</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">为一种特殊的空</span><span style="font-family:Calibri;">slotspan</span><span style="font-family:宋体;">，它里面的内存页处于</span><span style="font-family:Calibri;">decommitted</span><span style="font-family:宋体;">状态，这是典型的</span><span style="font-family:Calibri;">slab</span><span style="font-family:宋体;">结构。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h2 style="margin-left:0.0000pt;text-indent:0.0000pt;mso-list:l0 level2 lfo1;"><span style="font-family:Arial;mso-fareast-font-family:黑体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;">1.5 </span><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:Arial;mso-fareast-font-family:黑体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;">SlotSpanMetadata</span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:Arial;mso-fareast-font-family:黑体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">partition_allocator/partition_page.h</span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">SlotSpanMetadata</span> {</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">private</span>:</span></code><code><span class="code-snippet_outer">  PartitionFreelistEntry* freelist_head = <span class="code-snippet__literal">nullptr</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">public</span>:</span></code><code><span class="code-snippet_outer">  SlotSpanMetadata&lt;thread_safe&gt;* next_slot_span = <span class="code-snippet__literal">nullptr</span>;</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__function">PA_ALWAYS_INLINE PartitionFreelistEntry* <span class="code-snippet__title">PopForAlloc</span><span class="code-snippet__params">(<span class="code-snippet__keyword">size_t</span> size)</span></span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__function">PA_ALWAYS_INLINE PartitionFreelistEntry* <span class="code-snippet__title">get_freelist_head</span><span class="code-snippet__params">()</span> <span class="code-snippet__keyword">const</span> </span>{</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">return</span> freelist_head;</span></code><code><span class="code-snippet_outer">  }</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__function">PA_ALWAYS_INLINE <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">SetFreelistHead</span><span class="code-snippet__params">(PartitionFreelistEntry* new_head)</span></span>;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">    SlotSpanMetadata</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">是所有</span><span style="font-family:Calibri;">slot</span><span style="font-family:宋体;">的管理结构，每个</span><span style="font-family:Calibri;">slot</span><span style="font-family:宋体;">是由</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">PartitionFreelistEntry</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">表示。</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer">partition_allocator/partition_freelist_entry.h</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">PartitionFreelistEntry</span> {</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__function">PA_ALWAYS_INLINE <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">SetNext</span>(<span class="code-snippet__params">PartitionFreelistEntry* entry</span>)</span> {</span></code><code><span class="code-snippet_outer">    encoded_next_ = EncodedPartitionFreelistEntryPtr(entry);</span></code><code><span class="code-snippet_outer">  }</span></code><code><span class="code-snippet_outer">  EncodedPartitionFreelistEntryPtr encoded_next_;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">    SetNext</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">设置下一个</span><span style="font-family:Calibri;">next entry</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">EncodedPartitionFreelistEntryPtr</span> {</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">private</span>:</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__function">PA_ALWAYS_INLINE constexpr <span class="code-snippet__keyword">explicit</span> <span class="code-snippet__title">EncodedPartitionFreelistEntryPtr</span>(<span class="code-snippet__params"></span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">      std::nullptr_t</span>)</span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">      : <span class="code-snippet__title">encoded_</span>(<span class="code-snippet__params">Transform(<span class="code-snippet__number">0</span></span>))</span> {}</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__function">PA_ALWAYS_INLINE <span class="code-snippet__keyword">explicit</span> <span class="code-snippet__title">EncodedPartitionFreelistEntryPtr</span>(<span class="code-snippet__params"><span class="code-snippet__keyword">void</span>* ptr</span>)</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">      : <span class="code-snippet__title">encoded_</span>(<span class="code-snippet__params">Transform(reinterpret_cast&lt;uintptr_t&gt;(ptr</span>)))</span> {}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">  PA_ALWAYS_INLINE PartitionFreelistEntry* Decode() <span class="code-snippet__keyword">const</span> {</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">return</span> reinterpret_cast&lt;PartitionFreelistEntry*&gt;(Transform(encoded_));</span></code><code><span class="code-snippet_outer">  }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__function">PA_ALWAYS_INLINE constexpr uintptr_t <span class="code-snippet__title">Inverted</span>(<span class="code-snippet__params"></span>) <span class="code-snippet__keyword">const</span></span> { <span class="code-snippet__keyword">return</span> ~encoded_; }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__function">PA_ALWAYS_INLINE constexpr <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">Override</span>(<span class="code-snippet__params">uintptr_t encoded</span>)</span> {</span></code><code><span class="code-snippet_outer">    encoded_ = encoded;</span></code><code><span class="code-snippet_outer">  }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__function">PA_ALWAYS_INLINE constexpr <span class="code-snippet__keyword">explicit</span> <span class="code-snippet__keyword">operator</span> <span class="code-snippet__title">bool</span>(<span class="code-snippet__params"></span>) <span class="code-snippet__keyword">const</span></span> { <span class="code-snippet__keyword">return</span> encoded_; }</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> defined(ARCH_CPU_BIG_ENDIAN)</span></span></code><code><span class="code-snippet_outer">    uintptr_t transformed = ~address;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">else</span></span></span></code><code><span class="code-snippet_outer">    uintptr_t transformed = ReverseBytes(address);</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">return</span> transformed;</span></code><code><span class="code-snippet_outer">  }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">  uintptr_t encoded_;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">  friend PartitionFreelistEntry;</span></code><code><span class="code-snippet_outer">};</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">    EncodedPartitionFreelistEntryPtr</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">将</span><span style="font-family:Calibri;">entry</span><span style="font-family:宋体;">进行了一些编码转换。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    ProvisionMoreSlotsAndAllocOne</span><span style="font-family:宋体;">用来初始化一个</span><span style="font-family:Calibri;">slotspan</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="xml"><code><span class="code-snippet_outer">PA_ALWAYS_INLINE uintptr_t</span></code><code><span class="code-snippet_outer">PartitionBucket<span class="code-snippet__tag">&lt;<span class="code-snippet__name">thread_safe</span>&gt;</span>::ProvisionMoreSlotsAndAllocOne(</span></code><code><span class="code-snippet_outer">    PartitionRoot<span class="code-snippet__tag">&lt;<span class="code-snippet__name">thread_safe</span>&gt;</span>* root,</span></code><code><span class="code-snippet_outer">SlotSpanMetadata<span class="code-snippet__tag">&lt;<span class="code-snippet__name">thread_safe</span>&gt;</span>* slot_span) {</span></code><code><span class="code-snippet_outer">  size_t num_slots = slot_span-&gt;num_unprovisioned_slots;</span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  需要扩展的</span><span style="font-family:Calibri;">slot</span><span style="font-family:宋体;">数目。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">uintptr_t</span> slot_span_start =</span></code><code><span class="code-snippet_outer">      SlotSpanMetadata&lt;thread_safe&gt;::ToSlotSpanStart(slot_span);</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  通过</span><span style="font-family:Calibri;">slot_span</span><span style="font-family:宋体;">换算出第一个</span><span style="font-family:Calibri;">slot</span><span style="font-family:宋体;">的内存地址。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">PartitionFreelistEntry* prev_entry = <span class="code-snippet__literal">nullptr</span>;</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">uintptr_t</span> next_slot_end = next_slot + slot_size;</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">size_t</span> free_list_entries_added = <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">while</span> (next_slot_end &lt;= commit_end) {</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">void</span>* next_slot_ptr;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span> (PA_LIKELY(slot_size &lt;= kMaxMemoryTaggingSize)) {</span></code><code><span class="code-snippet_outer">      next_slot_ptr = TagMemoryRangeRandomly(next_slot, slot_size);</span></code><code><span class="code-snippet_outer">    } <span class="code-snippet__keyword">else</span> {</span></code><code><span class="code-snippet_outer">      next_slot_ptr = <span class="code-snippet__keyword">reinterpret_cast</span>&lt;<span class="code-snippet__keyword">void</span>*&gt;(next_slot);</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">auto</span>* entry = PartitionFreelistEntry::EmplaceAndInitNull(next_slot_ptr);</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span> (!slot_span-&gt;get_freelist_head()) {</span></code><code><span class="code-snippet_outer">      PA_DCHECK(!prev_entry);</span></code><code><span class="code-snippet_outer">      PA_DCHECK(!free_list_entries_added);</span></code><code><span class="code-snippet_outer">      slot_span-&gt;SetFreelistHead(entry);</span></code><code><span class="code-snippet_outer">    } <span class="code-snippet__keyword">else</span> {</span></code><code><span class="code-snippet_outer">      PA_DCHECK(free_list_entries_added);</span></code><code><span class="code-snippet_outer">      prev_entry-&gt;SetNext(entry);</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">    next_slot = next_slot_end;</span></code><code><span class="code-snippet_outer">    next_slot_end = next_slot + slot_size;</span></code><code><span class="code-snippet_outer">    prev_entry = entry;</span></code><code><span class="code-snippet_outer">  }</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style="margin-left: 21pt;"><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">循环调用</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">SetNext</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">填充下一个</span><span style="font-family:Calibri;">entry</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h2><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">1.6 ThreadCache</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  每个线程有一个独立的</span><span style="font-family:Calibri;">ThreadCache</span><span style="font-family:宋体;">，不需要上锁，以下是笔者提取出来的关键数据结构：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">partition_allocator/thread_cache.<span class="code-snippet__function">h</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">class <span class="code-snippet__title">PA_COMPONENT_EXPORT</span><span class="code-snippet__params">(PARTITION_ALLOC)</span> ThreadCache </span>{</span></code><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">Init</span><span class="code-snippet__params">(PartitionRoot&lt;&gt;* root)</span></span>;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">static</span> ThreadCache* <span class="code-snippet__title">Get</span><span class="code-snippet__params">()</span> </span>{</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> PA_CONFIG(THREAD_CACHE_FAST_TLS)</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">return</span> internal::g_thread_cache;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">else</span></span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">return</span> <span class="code-snippet__keyword">reinterpret_cast</span>&lt;ThreadCache*&gt;(</span></code><code><span class="code-snippet_outer">        internal::PartitionTlsGet(internal::g_thread_cache_key));</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#endi</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">static</span> ThreadCache* <span class="code-snippet__title">Create</span><span class="code-snippet__params">(PartitionRoot&lt;&gt;* root)</span></span>;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__function">PA_ALWAYS_INLINE uintptr_t <span class="code-snippet__title">GetFromCache</span><span class="code-snippet__params">(<span class="code-snippet__keyword">size_t</span> bucket_index,</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">                                          <span class="code-snippet__keyword">size_t</span>* slot_size)</span>;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">void</span> <span class="code-snippet__title">FillBucket</span><span class="code-snippet__params">(<span class="code-snippet__keyword">size_t</span> bucket_index)</span></span>;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__function">ThreadCache* next_ <span class="code-snippet__title">PA_GUARDED_BY</span><span class="code-snippet__params">(ThreadCacheRegistry::GetLock())</span></span>;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__function">ThreadCache* prev_ <span class="code-snippet__title">PA_GUARDED_BY</span><span class="code-snippet__params">(ThreadCacheRegistry::GetLock())</span></span>;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  线程通过</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">RegisterThreadCache</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">注册自己的</span><span style="font-family:Calibri;">cache</span><span style="font-family:宋体;">结构， 每个线程的</span><span style="font-family:Calibri;">cache</span><span style="font-family:宋体;">通过双向链表链接。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">    GetFromCache</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">函数从线程的当前</span><span style="font-family:Calibri;">cache</span><span style="font-family:宋体;">中选取一个</span><span style="font-family:Calibri;">slot</span><span style="font-family:宋体;">出来。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">PA_ALWAYS_INLINE <span class="code-snippet__keyword">uintptr_t</span> ThreadCache::GetFromCache(<span class="code-snippet__keyword">size_t</span> bucket_index,</span></code><code><span class="code-snippet_outer">                                                     <span class="code-snippet__keyword">size_t</span>* slot_size) {</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">auto</span>&amp; bucket = buckets_[bucket_index];</span></code><code><span class="code-snippet_outer">  internal::PartitionFreelistEntry* entry = bucket.freelist_head;</span></code><code><span class="code-snippet_outer">  internal::PartitionFreelistEntry* next =</span></code><code><span class="code-snippet_outer">      entry-&gt;GetNextForThreadCache&lt;<span class="code-snippet__literal">true</span>&gt;(bucket.slot_size);</span></code><code><span class="code-snippet_outer">  bucket.freelist_head = next;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"> 直接从</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">bucket.freelist_head</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">取出当前空闲的</span><span style="font-family:Calibri;">entry</span><span style="font-family:宋体;">地址，并设置下一个空闲的</span><span style="font-family:Calibri;">entry</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">    FillBucket</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">函数填充</span><span style="font-family:Calibri;">cache</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">bucket</span><span style="font-family:宋体;">对象。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="php"><code><span class="code-snippet_outer">void ThreadCache::FillBucket(size_t bucket_index) {</span></code><code><span class="code-snippet_outer">  Bucket&amp; bucket = buckets_[bucket_index];</span></code><code><span class="code-snippet_outer">  int count = std::max(</span></code><code><span class="code-snippet_outer">      <span class="code-snippet__number">1</span>, bucket.limit.load(std::memory_order_relaxed) / kBatchFillRatio);</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">for</span> (int i = <span class="code-snippet__number">0</span>; i &lt; count; i++) {</span></code><code><span class="code-snippet_outer">    uintptr_t slot_start = root_-&gt;AllocFromBucket(</span></code><code><span class="code-snippet_outer">        &amp;root_-&gt;buckets[bucket_index],</span></code><code><span class="code-snippet_outer">        AllocFlags::kFastPathOrReturnNull | AllocFlags::kReturnNull,</span></code><code><span class="code-snippet_outer">        root_-&gt;buckets[bucket_index].slot_size <span class="code-snippet__comment">/* raw_size */</span>,</span></code><code><span class="code-snippet_outer">        internal::PartitionPageSize(), &amp;usable_size, &amp;is_already_zeroed);</span></code><code><span class="code-snippet_outer">      PutInBucket(bucket, slot_start);</span></code><code><span class="code-snippet_outer">  }</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  循环调用</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">AllocFromBucket</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">分配内存，调用</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">PutInBucket</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">填充进去。</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">     PutInBucket</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">函数将</span><span style="font-family:Calibri;">slot</span><span style="font-family:宋体;">写入</span><span style="font-family:Calibri;">cache</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">buket</span><span style="font-family:宋体;">对象里。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">A_ALWAYS_INLINE <span class="code-snippet__keyword">void</span> ThreadCache::PutInBucket(Bucket&amp; bucket,</span></code><code><span class="code-snippet_outer">                                               <span class="code-snippet__keyword">uintptr_t</span> slot_start) {</span></code><code><span class="code-snippet_outer">  slot_size_remaining_in_16_bytes = <span class="code-snippet__built_in">std</span>::min(</span></code><code><span class="code-snippet_outer">      slot_size_remaining_in_16_bytes, distance_to_next_cacheline_in_16_bytes);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">const</span> <span class="code-snippet__keyword">uint32_t</span> poison_16_bytes[<span class="code-snippet__number">4</span>] = {<span class="code-snippet__number">0xbadbad00</span>, <span class="code-snippet__number">0xbadbad00</span>,</span></code><code><span class="code-snippet_outer">                                              <span class="code-snippet__number">0xbadbad00</span>, <span class="code-snippet__number">0xbadbad00</span>};</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> PA_HAS_BUILTIN(__builtin_assume_aligned)</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">void</span>* slot_start_tagged = __builtin_assume_aligned(</span></code><code><span class="code-snippet_outer">      internal::SlotStartAddr2Ptr(slot_start), internal::kAlignment);</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">else</span></span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">void</span>* slot_start_tagged = internal::SlotStartAddr2Ptr(slot_start);</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">uint32_t</span>* address_aligned = <span class="code-snippet__keyword">static_cast</span>&lt;<span class="code-snippet__keyword">uint32_t</span>*&gt;(slot_start_tagged);</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">for</span> (<span class="code-snippet__keyword">int</span> i = <span class="code-snippet__number">0</span>; i &lt; slot_size_remaining_in_16_bytes; i++) {</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__built_in">memcpy</span>(address_aligned, poison_16_bytes, <span class="code-snippet__keyword">sizeof</span>(poison_16_bytes));</span></code><code><span class="code-snippet_outer">    address_aligned += <span class="code-snippet__number">4</span>;</span></code><code><span class="code-snippet_outer">  }</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  如果是</span><span style="font-family:Calibri;">x86_64</span><span style="font-family:宋体;">架构，会将</span><span style="font-family:Calibri;">slot</span><span style="font-family:宋体;">填充一些固定的</span><span style="font-family:Calibri;">posion</span><span style="font-family:宋体;">值，防止</span><span style="font-family:Calibri;">UAF</span><span style="font-family:宋体;">漏洞。作者在注释中说明只在</span><span style="font-family:Calibri;">cache</span><span style="font-family:宋体;">中加入</span><span style="font-family:Calibri;">posion</span><span style="font-family:宋体;">是为了提高性能。那么另一个问题</span><span style="font-family:Calibri;">arm64</span><span style="font-family:宋体;">架构不使用</span><span style="font-family:Calibri;">cache posion</span><span style="font-family:宋体;">的原因可能是内存大小问题了。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="php"><code><span class="code-snippet_outer">auto* entry = internal::PartitionFreelistEntry::EmplaceAndInitForThreadCache(</span></code><code><span class="code-snippet_outer">      slot_start, bucket.freelist_head);</span></code><code><span class="code-snippet_outer">bucket.freelist_head = entry;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  将</span><span style="font-family:Calibri;">slot</span><span style="font-family:宋体;">写入</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">bucket.freelist_head</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">。</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h1><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;"><span style="font-family:Calibri;">2 </span><span style="font-family:宋体;">内存结构</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;"><o:p></o:p></span></strong></h1><h2><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">2.1 DirectMapped</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  对于</span><span style="font-family:Calibri;">buckets</span><span style="font-family:宋体;">数组中的内存块大小，</span><span style="font-family:Calibri;">PartitionAlloc</span><span style="font-family:宋体;">根据其大小，可以直接使用叫做</span><span style="font-family:Calibri;">DirectMapped</span><span style="font-family:宋体;">的技术，它要求待分配的内存大小不能超过</span><span style="font-family:Calibri;">2&gt;&gt;31 - 2mb</span><span style="font-family:宋体;">大小，并且这部分内存直接使用</span><span style="font-family:Calibri;">mmap</span><span style="font-family:宋体;">映射，使用</span><span style="font-family:Calibri;">ReservationOffsetTable</span><span style="font-family:宋体;">对其进行引用。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">partition_allocator/reservation_offset_table.<span class="code-snippet__function">h</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">class <span class="code-snippet__title">PA_COMPONENT_EXPORT</span><span class="code-snippet__params">(PARTITION_ALLOC)</span> ReservationOffsetTable </span>{</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> _<span class="code-snippet__title">ReservationOffsetTable</span> {</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">uint16_t</span> offsets[kReservationOffsetTableLength] = {};</span></code><code><span class="code-snippet_outer">  }</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> _<span class="code-snippet__title">PaddedReservationOffsetTables</span> {</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">char</span> pad_[PA_PKEY_ARRAY_PAD_SZ(_ReservationOffsetTable, kNumPools)] = {};</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> _<span class="code-snippet__title">ReservationOffsetTable</span> <span class="code-snippet__title">tables</span>[<span class="code-snippet__title">kNumPools</span>];</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">char</span> pad_after_[PA_PKEY_FILL_PAGE_SZ(<span class="code-snippet__keyword">sizeof</span>(_ReservationOffsetTable))] = {};</span></code><code><span class="code-snippet_outer">  };</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">static</span> PA_CONSTINIT _PaddedReservationOffsetTables</span></code><code><span class="code-snippet_outer">      padded_reservation_offset_tables_ PA_PKEY_ALIGN;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    offsets</span><span style="font-family:宋体;">数组保存了一个</span><span style="font-family:Calibri;">DirectMapped</span><span style="font-family:宋体;">内存块在对应的</span><span style="font-family:Calibri;">pool</span><span style="font-family:宋体;">中的偏移。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="properties"><code><span class="code-snippet_outer"><span class="code-snippet__attr">PA_ALWAYS_INLINE</span> <span class="code-snippet__string">uint16_t* GetReservationOffsetTable(pool_handle handle) {</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__meta">PA_DCHECK(kNullPoolHandle</span> <span class="code-snippet__string">&lt; handle &amp;&amp; handle &lt;= kNumPools);</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__attr">return</span> <span class="code-snippet__string">ReservationOffsetTable::padded_reservation_offset_tables_</span></span></code><code><span class="code-snippet_outer">      <span class="code-snippet__meta">.tables[handle</span> <span class="code-snippet__string">- 1]</span></span></code><code><span class="code-snippet_outer">      <span class="code-snippet__attr">.offsets;</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">}</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">PA_ALWAYS_INLINE</span> <span class="code-snippet__string">uint16_t* ReservationOffsetPointer(pool_handle pool,</span></span></code><code><span class="code-snippet_outer">                                                    <span class="code-snippet__attr">uintptr_t</span> <span class="code-snippet__string">offset_in_pool) {</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__attr">size_t</span> <span class="code-snippet__string">table_index = offset_in_pool &gt;&gt; kSuperPageShift;</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__meta">PA_DCHECK(table_index</span> <span class="code-snippet__string">&lt;</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__attr">ReservationOffsetTable</span>:<span class="code-snippet__string">:kReservationOffsetTableLength);</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__attr">return</span> <span class="code-snippet__string">GetReservationOffsetTable(pool) + table_index;</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">}</span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  每个</span><span style="font-family:Calibri;">DirectMapped</span><span style="font-family:宋体;">内存块通过双向链表链接，保存在</span><span style="font-family:Calibri;">root-&gt;direct_map_list</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    DirectMapped</span><span style="font-family:宋体;">内存结构如下：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100000173" data-ratio="0.07777777777777778" data-s="300,640" style="" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=fd73b3cd&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_png%2F4iaJia7Cvd3PCnqCX6ZrmoQ61QHfyMzzTgwtkM9FCicraE3oakbO6J0m3xKSxklqhYBTk96tq09sRL0vY4bsfAPjA%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><h2><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">2.2 Normal Map</span></span></strong></h2><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100000174" data-ratio="0.06574074074074074" data-s="300,640" style="" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=a3a698f9&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_png%2F4iaJia7Cvd3PCnqCX6ZrmoQ61QHfyMzzTggaujCicIfmHjpXoPLtGf5RgqSpOah7l6TSMQAbHK4ELtIWtFroEa7uQ%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    SlotSpan</span><span style="font-family:宋体;">中的一个</span><span style="font-family:Calibri;">slot</span><span style="font-family:宋体;">通过</span><span style="font-family:Calibri;">FromAddr</span><span style="font-family:宋体;">函数可以转为对应的</span><span style="font-family:Calibri;">SlotSpanMetadata</span><span style="font-family:宋体;">管理结构。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">PA_ALWAYS_INLINE PartitionPage&lt;thread_safe&gt;*</span></code><code><span class="code-snippet_outer">PartitionPage&lt;thread_safe&gt;::FromAddr(<span class="code-snippet__keyword">uintptr_t</span> address) {</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">uintptr_t</span> super_page = address &amp; kSuperPageBaseMask;</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">uintptr_t</span> partition_page_index =</span></code><code><span class="code-snippet_outer">      (address &amp; kSuperPageOffsetMask) &gt;&gt; PartitionPageShift();</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">return</span> PartitionSuperPageToMetadataArea&lt;thread_safe&gt;(super_page) +</span></code><code><span class="code-snippet_outer">         partition_page_index;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><h1><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;"><span style="font-family:Calibri;">3 </span><span style="font-family:宋体;">内存分配算法</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;"><o:p></o:p></span></strong></h1><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"> 话不多说，直接上图：</span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100000175" data-ratio="0.9018518518518519" data-s="300,640" style="" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=3d9b0952&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_png%2F4iaJia7Cvd3PCnqCX6ZrmoQ61QHfyMzzTgItZUN9t8CoVz3TRU7frdeGOntBrlbRDuuFGVruhpF9E1QFvgotd2HA%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/><span style="font-family: Calibri;font-size: 10.5pt;letter-spacing: 0.034em;text-align: justify;"></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  最终分配好的</span><span style="font-family:Calibri;">object</span><span style="font-family:宋体;">在内存中的结构为：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100000176" data-ratio="1" data-s="300,640" style="" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=75f1f148&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_png%2F4iaJia7Cvd3PCnqCX6ZrmoQ61QHfyMzzTg9pubHcTFTwjgwFK36SbmevucyOmYZj5eqgNicL0lZn6Vic9yCQpt0cxw%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p style="display: none;"><mp-style-type data-value="3"></mp-style-type></p>



<p><a href="2247483827">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=fd588ed5&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg4NjU1NDU4MA%3D%3D%26mid%3D2247483827%26idx%3D1%26sn%3De0df8e57dba39d003d2458b83af41744%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Mon, 11 Mar 2024 12:11:00 +0800</pubDate>
    </item>
    <item>
      <title>三星RKP内核完整性保护程序分析</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg4NjU1NDU4MA==&amp;mid=2247483819&amp;idx=1&amp;sn=d74ac929c46c49e89ec0fb69842abb1b</link>
      <description>本文主要以三星s6与s20二进制为样本对内核完整性保护程序RKP进行分析。</description>
      <content:encoded><![CDATA[<p>
<span>wzt</span> <span>2024-03-06 11:46</span> <span style="display: inline-block;">上海</span>
</p>

<p>本文主要以三星s6与s20二进制为样本对内核完整性保护程序RKP进行分析。</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=f7022630&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_jpg%2F4iaJia7Cvd3PDCM6QMDyJkP6ibiaT8KvkJ9khpF2dHd75BlBiaTZJUepSevD96ibmdCY84R3OLEPTy1ibj0c9ObaeYiboQ%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<h1><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;"><span style="font-family:Calibri;">1 </span><span style="font-family:宋体;">功能分析</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;"><o:p></o:p></span></strong></h1><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  本文主要以三星</span><span style="font-family:Calibri;">s6</span><span style="font-family:宋体;">与</span><span style="font-family:Calibri;">s20</span><span style="font-family:宋体;">二进制为样本进行分析。</span><span style="font-family:Calibri;">S6</span><span style="font-family:宋体;">在</span><span style="font-family:Calibri;">2016</span><span style="font-family:宋体;">年发布，这个版本由于有符号存在，可以大大降低逆向工程分析的难度，对于</span><span style="font-family:Calibri;">s20</span><span style="font-family:宋体;">二进制只做部分参考分析。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h2 style="margin-left:0.0000pt;text-indent:0.0000pt;mso-list:l0 level2 lfo1;"><span style="font-family:Arial;mso-fareast-font-family:黑体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;">1.1 </span><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">Cred</span><span style="font-family:黑体;">保护</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  内核</span><span style="font-family:Calibri;">Struct cred</span><span style="font-family:宋体;">数据结构保存了进程的权限凭证如</span><span style="font-family:Calibri;">uid/gid</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">capability</span><span style="font-family:宋体;">等，是内核漏洞攻击程序进行权限提升必须要更改的数据结构，因此对</span><span style="font-family:Calibri;">cred</span><span style="font-family:宋体;">数据结构的保护至关重要。三星</span><span style="font-family:Calibri;">rkp</span><span style="font-family:宋体;">在</span><span style="font-family:Calibri;">el2</span><span style="font-family:宋体;">限制了</span><span style="font-family:Calibri;">cred</span><span style="font-family:宋体;">在</span><span style="font-family:Calibri;">el1</span><span style="font-family:宋体;">为只读，当内核对</span><span style="font-family:Calibri;">cred</span><span style="font-family:宋体;">进行正常写操作时，通过</span><span style="font-family:Calibri;">rkp</span><span style="font-family:宋体;">接口调用</span><span style="font-family:Calibri;">el2</span><span style="font-family:宋体;">层函数对其进行写操作。但</span><span style="font-family:Calibri;">rkp</span><span style="font-family:宋体;">除了对</span><span style="font-family:Calibri;">cred</span><span style="font-family:宋体;">做只读保护外， 还在</span><span style="font-family:Calibri;">cred</span><span style="font-family:宋体;">数据结构引入了两个字段</span><span style="font-family:Calibri;">bp_task</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">bp_pgd</span><span style="font-family:宋体;">对</span><span style="font-family:Calibri;">cred</span><span style="font-family:宋体;">做完整性校验以及</span><span style="font-family:Calibri;">struct task_security_struct</span><span style="font-family:宋体;">结构加入</span><span style="font-family:Calibri;">bp_cred</span><span style="font-family:宋体;">字段，防止被其他进程篡改。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">cred</span> {</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">atomic_t</span>        usage;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">kuid_t</span>          uid;            <span class="code-snippet__comment">/* real UID of the task */</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">kgid_t</span>          gid;            <span class="code-snippet__comment">/* real GID of the task */</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">kuid_t</span>          suid;           <span class="code-snippet__comment">/* saved UID of the task */</span></span></code><code><span class="code-snippet_outer">...</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">union</span> {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">int</span> non_rcu;                    <span class="code-snippet__comment">/* Can we skip RCU deletion? */</span></span></code><code><span class="code-snippet_outer">                <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">rcu_head</span> <span class="code-snippet__title">rcu</span>;</span>            <span class="code-snippet__comment">/* RCU deletion hook */</span></span></code><code><span class="code-snippet_outer">        };</span></code><code><span class="code-snippet_outer">} __randomize_layout;</span></code></pre></section><p style=""><br/></p><h3 style="margin-left:0.0000pt;text-indent:0.0000pt;mso-list:l0 level3 lfo1;"><span style="font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;">1.1.1 </span><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">反向</span><span style="font-family:Calibri;">task_struct</span><span style="font-family:宋体;">指针保护</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h3><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  当内核需要对</span><span style="font-family:Calibri;">cred</span><span style="font-family:宋体;">进行创建和更新时，</span><span style="font-family:Calibri;">bp_task</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">bp_pgd</span><span style="font-family:宋体;">就需要同步更新。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  对于</span><span style="font-family:Calibri;">bp_task</span><span style="font-family:宋体;">，内核在</span><span style="font-family:Calibri;">prepare_ro_creds</span><span style="font-family:宋体;">函数里通过调用如下</span><span style="font-family:Calibri;">rkp</span><span style="font-family:宋体;">接口：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer">drivers/uh/kdp.c</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">struct</span> cred *prepare_ro_creds(<span class="code-snippet__keyword">struct</span> cred *old, <span class="code-snippet__keyword">int</span> kdp_cmd, u64 p)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        memset((<span class="code-snippet__keyword">void</span> *)&amp;param_data, <span class="code-snippet__number">0</span>, <span class="code-snippet__keyword">sizeof</span>(<span class="code-snippet__keyword">struct</span> cred_param));</span></code><code><span class="code-snippet_outer">        param_data.cred = &amp;temp_old;</span></code><code><span class="code-snippet_outer">        param_data.cred_ro = new_ro;</span></code><code><span class="code-snippet_outer">        param_data.use_cnt_ptr = use_cnt_ptr;</span></code><code><span class="code-snippet_outer">        param_data.sec_ptr = tsec;</span></code><code><span class="code-snippet_outer">        param_data.type = kdp_cmd;</span></code><code><span class="code-snippet_outer">        param_data.use_cnt = (u64)p;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        uh_call(UH_APP_KDP, PREPARE_RO_CRED, (u64)&amp;param_data, (u64)current, (u64)&amp;init_cred, (u64)&amp;init_cred_kdp);</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  对应的</span><span style="font-family:Calibri;">el2</span><span style="font-family:宋体;">层函数操作为：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100000161" data-ratio="0.23703703703703705" data-s="300,640" style="" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=e1321206&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_png%2F4iaJia7Cvd3PDCM6QMDyJkP6ibiaT8KvkJ9kUibA0MfKrhXCe5Whxgz01KezAia7XRuQ0TESPF7x9jibaKl6iaLf3wN1ibg%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><h3 style="text-indent:21.0000pt;"><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:normal;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">通过</span><span style="font-family:Calibri;">rkp_assign_creds</span><span style="font-family:宋体;">对</span><span style="font-family:Calibri;">cred</span><span style="font-family:宋体;">结构体的</span><span style="font-family:Calibri;">CRED_BP_TASK_OFFSET</span><span style="font-family:宋体;">偏移进行赋值。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:normal;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></h3><h3 style="margin-left:0.0000pt;text-indent:0.0000pt;mso-list:l0 level3 lfo1;"><span style="font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;">1.1.2 </span><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">反向</span><span style="font-family:Calibri;">pgd</span><span style="font-family:宋体;">指针保护</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h3><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  对于</span><span style="font-family:Calibri;">bp_pgd</span><span style="font-family:宋体;">，内核提供</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">kdp_assign_pgd</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">进行操作。</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="php"><code><span class="code-snippet_outer">void kdp_assign_pgd(struct task_struct *p)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        u64 pgd = (u64)(p-&gt;mm ? p-&gt;mm-&gt;pgd : swapper_pg_dir);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        uh_call(UH_APP_KDP, SET_CRED_PGD, (u64)p-&gt;cred, (u64)pgd, <span class="code-snippet__number">0</span>, <span class="code-snippet__number">0</span>);</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  对应的</span><span style="font-family:Calibri;">el2</span><span style="font-family:宋体;">层函数操作为：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100000162" data-ratio="0.2101851851851852" data-s="300,640" style="" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=30b0f3ec&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_png%2F4iaJia7Cvd3PDCM6QMDyJkP6ibiaT8KvkJ9kZBcEQw4gW2cxsMGtgYcHpcUN3b5h9FgM2Q8su9eo7jShCR9ic34Ygzw%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><h3 style="text-indent:21.0000pt;"><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:normal;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">通过</span><span style="font-family:Calibri;">rkp_pgd_assign</span><span style="font-family:宋体;">对</span><span style="font-family:Calibri;">cred</span><span style="font-family:宋体;">结构体的</span><span style="font-family:Calibri;">CRED_BP_PGD_OFFSET</span><span style="font-family:宋体;">偏移进行赋值。</span></span><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h3><h3 style="margin-left:0.0000pt;text-indent:0.0000pt;mso-list:l0 level3 lfo1;"><span style="font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;">1.1.3 </span><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">task_security_struct</span><span style="font-family:宋体;">指针保护</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h3><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">security/selinux/hooks.<span class="code-snippet__function">c</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">cred_init_security</span><span class="code-snippet__params">(<span class="code-snippet__keyword">void</span>)</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">cred</span> *<span class="code-snippet__title">cred</span> = (<span class="code-snippet__title">struct</span> <span class="code-snippet__title">cred</span> *) <span class="code-snippet__title">current</span>-&gt;<span class="code-snippet__title">real_cred</span>;</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">task_security_struct</span> *<span class="code-snippet__title">tsec</span>;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">ifdef</span> CONFIG_KDP_CRED</span></span></code><code><span class="code-snippet_outer">        tsec = &amp;init_sec;</span></code><code><span class="code-snippet_outer">        tsec-&gt;bp_cred = cred;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment">// is not support 5.4 upper version, so we added</span></span></code><code><span class="code-snippet_outer">        cred-&gt;security = tsec;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">else</span></span></span></code><code><span class="code-snippet_outer">        tsec = selinux_cred(cred);</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code><code><span class="code-snippet_outer">        tsec-&gt;osid = tsec-&gt;sid = SECINITSID_KERNEL;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  内核调用</span><span style="font-family:Calibri;">cred_init_security</span><span style="font-family:宋体;">对</span><span style="font-family:Calibri;">init</span><span style="font-family:宋体;">进程进行初始化，后续子进程将会继承</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">struct task_security_struct</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">指针。当</span><span style="font-family:Calibri;">cred</span><span style="font-family:宋体;">需要更改时同样使用</span><span style="font-family:Calibri;">prepare_ro_creds</span><span style="font-family:宋体;">进行处理。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer">drivers/uh/kdp.c</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">struct</span> cred *prepare_ro_creds(<span class="code-snippet__keyword">struct</span> cred *old, <span class="code-snippet__keyword">int</span> kdp_cmd, u64 p)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        memset((<span class="code-snippet__keyword">void</span> *)&amp;param_data, <span class="code-snippet__number">0</span>, <span class="code-snippet__keyword">sizeof</span>(<span class="code-snippet__keyword">struct</span> cred_param));</span></code><code><span class="code-snippet_outer">        param_data.cred = &amp;temp_old;</span></code><code><span class="code-snippet_outer">        param_data.cred_ro = new_ro;</span></code><code><span class="code-snippet_outer">        param_data.use_cnt_ptr = use_cnt_ptr;</span></code><code><span class="code-snippet_outer">        param_data.sec_ptr = tsec;</span></code><code><span class="code-snippet_outer">        param_data.type = kdp_cmd;</span></code><code><span class="code-snippet_outer">        param_data.use_cnt = (u64)p;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        uh_call(UH_APP_KDP, PREPARE_RO_CRED, (u64)&amp;param_data, (u64)current, (u64)&amp;init_cred, (u64)&amp;init_cred_kdp);</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="font-family: 宋体;font-size: 10.5pt;letter-spacing: 0.034em;"> 对应的</span><span style="font-size: 10.5pt;letter-spacing: 0.034em;font-family: Calibri;">el2</span><span style="font-family: 宋体;font-size: 10.5pt;letter-spacing: 0.034em;">函数接口为：</span><br/></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100000163" data-ratio="0.2074074074074074" data-s="300,640" style="" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=b31b7571&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_png%2F4iaJia7Cvd3PDCM6QMDyJkP6ibiaT8KvkJ9kNicgibG64XicU1k6vhvVzAo4ZUQpABnV571kTkHKsjMnluKfeua3EKHUw%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><h3 style="text-indent:21.0000pt;"><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:normal;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">通过</span><span style="font-family:Calibri;">rkp_assign_secptr</span><span style="font-family:宋体;">对</span><span style="font-family:Calibri;">cred</span><span style="font-family:宋体;">结构体的</span><span style="font-family:Calibri;">CRED_SECURITY_OFFSET</span><span style="font-family:宋体;">偏移进行赋值。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:normal;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></h3><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">Rkp</span><span style="font-family:宋体;">加入这三个指针保护的目的是做完整性检查，在</span><span style="font-family:Calibri;">LSM</span><span style="font-family:宋体;">框架里调用</span><span style="font-family:Calibri;">hook</span><span style="font-family:宋体;">钩子之前加入判断语句：</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer">security/security.c</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">define</span> call_void_hook(FUNC, ...)                               \</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">do</span> {                                                    \</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">struct</span> security_hook_list *P;                   \</span></code><code><span class="code-snippet_outer">                                                                \</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span>(security_integrity_current()) <span class="code-snippet__keyword">break</span>;         \</span></code><code><span class="code-snippet_outer">                hlist_for_each_entry(P, &amp;security_hook_heads.FUNC, list) \</span></code><code><span class="code-snippet_outer">                        P-&gt;hook.FUNC(__VA_ARGS__);              \</span></code><code><span class="code-snippet_outer">        } <span class="code-snippet__keyword">while</span> (<span class="code-snippet__number">0</span>)</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">define</span> call_int_hook(FUNC, IRC, ...) ({                        \</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">int</span> RC = IRC;                                           \</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">do</span> {                                                    \</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">struct</span> security_hook_list *P;                   \</span></code><code><span class="code-snippet_outer">                                                                \</span></code><code><span class="code-snippet_outer">                RC = security_integrity_current();              \</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> (RC != <span class="code-snippet__number">0</span>)                                    \</span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">break</span>;                                  \</span></code><code><span class="code-snippet_outer">                hlist_for_each_entry(P, &amp;security_hook_heads.FUNC, list) { \</span></code><code><span class="code-snippet_outer">                        RC = P-&gt;hook.FUNC(__VA_ARGS__);         \</span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">if</span> (RC != <span class="code-snippet__number">0</span>)                            \</span></code><code><span class="code-snippet_outer">                                <span class="code-snippet__keyword">break</span>;                          \</span></code><code><span class="code-snippet_outer">                }                                               \</span></code><code><span class="code-snippet_outer">        } <span class="code-snippet__keyword">while</span> (<span class="code-snippet__number">0</span>);                                            \</span></code><code><span class="code-snippet_outer">        RC;                                                     \</span></code><code><span class="code-snippet_outer">})</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">drivers/uh/kdp.<span class="code-snippet__function">c</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">int</span> <span class="code-snippet__title">security_integrity_current</span>(<span class="code-snippet__params"><span class="code-snippet__keyword">void</span></span>)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">const</span> <span class="code-snippet__keyword">struct</span> cred *cur_cred = current_cred();</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        rcu_read_lock();</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (kdp_enable &amp;&amp;</span></code><code><span class="code-snippet_outer">                        (is_kdp_invalid_cred_sp((u64)cur_cred, (u64)cur_cred-&gt;security)</span></code><code><span class="code-snippet_outer">                        || cmp_sec_integrity(cur_cred, current-&gt;mm)</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#ifdef CONFIG_KDP_NS</span></span></code><code><span class="code-snippet_outer">                        || cmp_ns_integrity())) {</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">else</span></span></span></code><code><span class="code-snippet_outer">                        )) {</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code><code><span class="code-snippet_outer">                rcu_read_unlock();</span></code><code><span class="code-snippet_outer">                panic(<span class="code-snippet__string">&#34;KDP CRED PROTECTION VIOLATION\n&#34;</span>);</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">        rcu_read_unlock();</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">static</span> inline <span class="code-snippet__keyword">bool</span> <span class="code-snippet__title">is_kdp_invalid_cred_sp</span>(<span class="code-snippet__params">u64 cred, u64 sec_ptr</span>)</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> ((u64)tsec-&gt;bp_cred != cred) {</span></code><code><span class="code-snippet_outer">                printk(KERN_ERR, <span class="code-snippet__string">&#34;[KDP] %s: tesc-&gt;bp_cred: %lx, cred: %lx\n&#34;</span>,</span></code><code><span class="code-snippet_outer">                                __func__, (u64)tsec-&gt;bp_cred, cred);</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">return</span> <span class="code-snippet__literal">true</span>;</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> <span class="code-snippet__literal">false</span>;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="font-size: 10.5pt;"><span style="font-family:宋体;"> </span></span><span style="letter-spacing: 0.034em;font-family: Calibri;font-size: 10.5pt;">cmp_sec_integrity</span><span style="letter-spacing: 0.034em;font-family: 宋体;font-size: 10.5pt;">用来验证<span style="font-family:Calibri;">cred</span>数据结构的<span style="font-family:Calibri;">bp_task</span>和<span style="font-family:Calibri;">bp_pgd</span>指针是否被篡改。</span><br/></p><h2 style="margin-left:0.0000pt;text-indent:0.0000pt;mso-list:l0 level2 lfo1;"><span style="font-family:Arial;mso-fareast-font-family:黑体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;">1.2 </span><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">Namespace</span><span style="font-family:黑体;">保护</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">   Rkp</span><span style="font-family:宋体;">对</span><span style="font-family:Calibri;">Namespace</span><span style="font-family:宋体;">的保护目前仅局限于</span><span style="font-family:Calibri;">mount namespace</span><span style="font-family:宋体;">，对其保护的方式为验证</span><span style="font-family:Calibri;">nsproxy-&gt;mnt_ns-&gt;root</span><span style="font-family:宋体;">字段是否被篡改，同时还对</span><span style="font-family:Calibri;">mount</span><span style="font-family:宋体;">挂载点进行了只读保护，不能挂载新的分区以及二进制程序必须从可信的</span><span style="font-family:Calibri;">mount</span><span style="font-family:宋体;">点启动。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;"> 首先在</span><span style="font-family:Calibri;">vfsmount</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">mount</span><span style="font-family:宋体;">数据结构中都加入了互相指向的</span><span style="font-family:Calibri;">backup</span><span style="font-family:宋体;">指针：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">include/linux/mount.h</span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">vfsmount</span> {</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">dentry</span> *<span class="code-snippet__title">mnt_root</span>;</span>        <span class="code-snippet__comment">/* root of the mounted tree */</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">super_block</span> *<span class="code-snippet__title">mnt_sb</span>;</span>     <span class="code-snippet__comment">/* pointer to superblock */</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">int</span> mnt_flags;</span></code><code><span class="code-snippet_outer">        ANDROID_KABI_RESERVE(<span class="code-snippet__number">1</span>);</span></code><code><span class="code-snippet_outer">        ANDROID_KABI_RESERVE(<span class="code-snippet__number">2</span>);</span></code><code><span class="code-snippet_outer">        ANDROID_KABI_RESERVE(<span class="code-snippet__number">3</span>);</span></code><code><span class="code-snippet_outer">        ANDROID_KABI_RESERVE(<span class="code-snippet__number">4</span>);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">void</span> *data;</span></code><code><span class="code-snippet_outer">} __randomize_layout;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">ifdef</span> CONFIG_KDP_NS</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">kdp_vfsmount</span> {</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">vfsmount</span> <span class="code-snippet__title">mnt</span>;</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">mount</span> *<span class="code-snippet__title">bp_mount</span>;</span> <span class="code-snippet__comment">/* pointer to mount*/</span></span></code><code><span class="code-snippet_outer">};</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">fs/mount.h</span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">mount</span> {</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">hlist_node</span> <span class="code-snippet__title">mnt_hash</span>;</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">hlist_head</span> <span class="code-snippet__title">mnt_stuck_children</span>;</span></span></code><code><span class="code-snippet_outer">} __randomize_layout;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">ifdef</span> CONFIG_KDP_NS</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">kdp_mount</span> {</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">mount</span> <span class="code-snippet__title">mount</span>;</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">vfsmount</span> *<span class="code-snippet__title">mnt</span>;</span></span></code><code><span class="code-snippet_outer">};</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  内核通过调用</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">kdp_mnt_alloc_vfsmount</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">请求</span><span style="font-family:Calibri;">el2</span><span style="font-family:宋体;">进行指针设置。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">int</span> <span class="code-snippet__title">kdp_mnt_alloc_vfsmount</span>(<span class="code-snippet__params"><span class="code-snippet__keyword">struct</span> mount *mnt</span>)</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        uh_call(UH_APP_KDP, ALLOC_VFSMOUNT, (u64)vfsmnt, (u64)mnt, <span class="code-snippet__number">0</span>, <span class="code-snippet__number">0</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  对应的</span><span style="font-family:Calibri;">el2</span><span style="font-family:宋体;">函数操作为：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100000164" data-ratio="0.17222222222222222" data-s="300,640" style="" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=7212de1d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_png%2F4iaJia7Cvd3PDCM6QMDyJkP6ibiaT8KvkJ9k9YB2UZficAL30Bn56vlgNicDkBa0aAo7Npm8yGic4KCefHejod1Aak4jg%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><h2 style="text-indent:21.0000pt;"><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:normal;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">El2</span><span style="font-family:宋体;">通过</span><span style="font-family:Calibri;">rkp_init_ns</span><span style="font-family:宋体;">对</span><span style="font-family:Calibri;">mount</span><span style="font-family:宋体;">结构的</span><span style="font-family:Calibri;">BPMNT_VFSMNT_OFFSET</span><span style="font-family:宋体;">偏移进行赋值。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:normal;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></h2><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">当</span><span style="font-family:Calibri;">LSM</span><span style="font-family:宋体;">框架的</span><span style="font-family:Calibri;">hook</span><span style="font-family:宋体;">钩子执行时，会调用</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">cmp_ns_integrity</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">进行指针完整性检查：</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="php"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">static</span> unsigned int cmp_ns_integrity(void)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        root = (struct kdp_mount *)current-&gt;nsproxy-&gt;mnt_ns-&gt;root;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (root != (struct kdp_mount *)((struct kdp_vfsmount *)root-&gt;mnt)-&gt;bp_mount) {</span></code><code><span class="code-snippet_outer">                printk(KERN_ERR <span class="code-snippet__string">&#34;[KDP] NameSpace Mismatch %lx != %lx\n nsp: 0x%lx, mnt_ns: 0x%lx\n&#34;</span>,</span></code><code><span class="code-snippet_outer">                                root, ((struct kdp_vfsmount *)root-&gt;mnt)-&gt;bp_mount, nsp, nsp-&gt;mnt_ns);</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">return</span> <span class="code-snippet__number">1</span>;</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  当内核挂载一个新的文件系统时，调用</span><span style="font-family:Calibri;">kdp_do_new_mount-&gt;kdp_populate_sb</span><span style="font-family:宋体;">来对指定的白名单分区做只读保护：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">kdp_populate_sb</span>(<span class="code-snippet__params"><span class="code-snippet__keyword">char</span> *mount_point, <span class="code-snippet__keyword">struct</span> vfsmount *mnt</span>)</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (!odm_sb &amp;&amp; !strncmp(mount_point, KDP_MOUNT_PRODUCT, KDP_MOUNT_PRODUCT_LEN))</span></code><code><span class="code-snippet_outer">                uh_call(UH_APP_KDP, SET_NS_SB_VFSMOUNT, (u64)&amp;odm_sb, (u64)mnt, KDP_SB_ODM, <span class="code-snippet__number">0</span>); </span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    Rkp</span><span style="font-family:宋体;">对以下的</span><span style="font-family:Calibri;">super_block</span><span style="font-family:宋体;">结构体做了只读保护：</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">static</span> <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">super_block</span> *<span class="code-snippet__title">rootfs_sb</span> __<span class="code-snippet__title">kdp_ro</span> = <span class="code-snippet__title">NULL</span>;</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">static</span> <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">super_block</span> *<span class="code-snippet__title">sys_sb</span> __<span class="code-snippet__title">kdp_ro</span> = <span class="code-snippet__title">NULL</span>;</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">static</span> <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">super_block</span> *<span class="code-snippet__title">odm_sb</span> __<span class="code-snippet__title">kdp_ro</span> = <span class="code-snippet__title">NULL</span>;</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">static</span> <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">super_block</span> *<span class="code-snippet__title">vendor_sb</span> __<span class="code-snippet__title">kdp_ro</span> = <span class="code-snippet__title">NULL</span>;</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">static</span> <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">super_block</span> *<span class="code-snippet__title">art_sb</span> __<span class="code-snippet__title">kdp_ro</span> = <span class="code-snippet__title">NULL</span>;</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">static</span> <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">super_block</span> *<span class="code-snippet__title">crypt_sb</span>     __<span class="code-snippet__title">kdp_ro</span> = <span class="code-snippet__title">NULL</span>;</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">static</span> <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">super_block</span> *<span class="code-snippet__title">dex2oat_sb</span>   __<span class="code-snippet__title">kdp_ro</span> = <span class="code-snippet__title">NULL</span>;</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">static</span> <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">super_block</span> *<span class="code-snippet__title">adbd_sb</span>              __<span class="code-snippet__title">kdp_ro</span> = <span class="code-snippet__title">NULL</span>;</span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"> 对应的分区名白名单为：</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">define</span> KDP_MOUNT_SYSTEM <span class="code-snippet__meta-string">&#34;/system&#34;</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">define</span> KDP_MOUNT_SYSTEM2 <span class="code-snippet__meta-string">&#34;/first_stage_ramdisk/system&#34;</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">define</span> KDP_MOUNT_PRODUCT <span class="code-snippet__meta-string">&#34;/product&#34;</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">define</span> KDP_MOUNT_VENDOR <span class="code-snippet__meta-string">&#34;/vendor&#34;</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">define</span> KDP_MOUNT_ART <span class="code-snippet__meta-string">&#34;/com.android.runtime&#34;</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">define</span> KDP_MOUNT_CRYPT <span class="code-snippet__meta-string">&#34;/com.android.conscrypt&#34;</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">define</span> KDP_MOUNT_DEX2OAT <span class="code-snippet__meta-string">&#34;/com.android.art&#34;</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">define</span> KDP_MOUNT_ADBD <span class="code-snippet__meta-string">&#34;/com.android.adbd&#34;</span></span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  当内核通过</span><span style="font-family:Calibri;">execve</span><span style="font-family:宋体;">执行一个新的二进制程序时，将会调用</span><span style="font-family:Calibri;">invalid_drive</span><span style="font-family:宋体;">函数来判断二进制程序是否从以上白名单分区中启动：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">int</span> <span class="code-snippet__title">invalid_drive</span>(<span class="code-snippet__params"><span class="code-snippet__keyword">struct</span> linux_binprm *bprm</span>)</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (!kdp_check_path_mismatch((<span class="code-snippet__keyword">struct</span> kdp_vfsmount *)vfsmnt)) {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">return</span> <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        sb = vfsmnt-&gt;mnt_sb;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (kdp_check_sb_mismatch(sb)) {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">return</span> <span class="code-snippet__number">1</span>;</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">    kdp_check_path_mismatch</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">忽略了以下白名单程序：</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js"><code><span class="code-snippet_outer">/com.android.runtime</span></code><code><span class="code-snippet_outer">/com.android.conscrypt</span></code><code><span class="code-snippet_outer">/com.android.art</span></code><code><span class="code-snippet_outer">/com.android.adbd</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">    kdp_check_sb_mismatch</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">检查是否来自以上白名单分区。</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">int</span> <span class="code-snippet__title">kdp_check_sb_mismatch</span>(<span class="code-snippet__params"><span class="code-snippet__keyword">struct</span> super_block *sb</span>)</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> ((sb != rootfs_sb) &amp;&amp; (sb != sys_sb) &amp;&amp; (sb != odm_sb)</span></code><code><span class="code-snippet_outer">                &amp;&amp; (sb != vendor_sb) &amp;&amp; (sb != art_sb) &amp;&amp; (sb != crypt_sb)</span></code><code><span class="code-snippet_outer">                &amp;&amp; (sb != dex2oat_sb) &amp;&amp; (sb != adbd_sb))</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">return</span> <span class="code-snippet__number">1</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><h2 style="margin-left:0.0000pt;text-indent:0.0000pt;mso-list:l0 level2 lfo1;"><span style="font-family:Arial;mso-fareast-font-family:黑体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;">1.3 </span><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;">二进制程序启动权限限制</span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    Rkp</span><span style="font-family:宋体;">在内核</span><span style="font-family:Calibri;">execve</span><span style="font-family:宋体;">执行一个二进制程序时，对每个二进制在</span><span style="font-family:Calibri;">el2</span><span style="font-family:宋体;">层做了一个标记，用于后续进行权限检查。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="php"><code><span class="code-snippet_outer">SYSCALL_DEFINE3(execve,</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">const</span> char __user *, filename,</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">const</span> char __user *<span class="code-snippet__keyword">const</span> __user *, argv,</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">const</span> char __user *<span class="code-snippet__keyword">const</span> __user *, envp)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">#ifdef CONFIG_KDP_CRED</span></span></code><code><span class="code-snippet_outer">                uh_call(UH_APP_KDP, MARK_PPT, (u64)path-&gt;name, (u64)current, <span class="code-snippet__number">0</span>, <span class="code-snippet__number">0</span>);</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> (current-&gt;cred-&gt;uid.val == <span class="code-snippet__number">0</span> || current-&gt;cred-&gt;gid.val == <span class="code-snippet__number">0</span> ||</span></code><code><span class="code-snippet_outer">                        current-&gt;cred-&gt;euid.val == <span class="code-snippet__number">0</span> || current-&gt;cred-&gt;egid.val == <span class="code-snippet__number">0</span> ||</span></code><code><span class="code-snippet_outer">                        current-&gt;cred-&gt;suid.val == <span class="code-snippet__number">0</span> || current-&gt;cred-&gt;sgid.val == <span class="code-snippet__number">0</span>) {</span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">if</span> (kdp_restrict_fork(path)) {</span></code><code><span class="code-snippet_outer">                                pr_warn(<span class="code-snippet__string">&#34;RKP_KDP Restricted making process. PID = %d(%s) PPID = %d(%s)\n&#34;</span>,</span></code><code><span class="code-snippet_outer">                                                current-&gt;pid, current-&gt;comm,</span></code><code><span class="code-snippet_outer">                                                current-&gt;parent-&gt;pid, current-&gt;parent-&gt;comm);</span></code><code><span class="code-snippet_outer">                                putname(path);</span></code><code><span class="code-snippet_outer">                                <span class="code-snippet__keyword">return</span> -EACCES;</span></code><code><span class="code-snippet_outer">                        }</span></code><code><span class="code-snippet_outer">                }</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">        putname(path);</span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">#endif</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> do_execve(getname(filename), argv, envp);</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    EL2</span><span style="font-family:宋体;">对应的</span><span style="font-family:Calibri;">MARK_PPT</span><span style="font-family:宋体;">操作为：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">__int64 __<span class="code-snippet__function">fastcall <span class="code-snippet__title">rkp_mark_ppt</span><span class="code-snippet__params">(__int64 a1)</span></span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">if</span> ( !(<span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">int</span>)sub_8000A578(v8, &amp;unk_80020F0C)<span class="code-snippet__comment">// /system/bin/</span></span></code><code><span class="code-snippet_outer">    || !(<span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">int</span>)sub_8000A578(v8, aSystemBinAppPr)<span class="code-snippet__comment">// /system/bin/app_process32</span></span></code><code><span class="code-snippet_outer">    || !(<span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">int</span>)sub_8000A578(v8, aSystemBinAppPr_0) )<span class="code-snippet__comment">// /system/bin/app_process64</span></span></code><code><span class="code-snippet_outer">  {</span></code><code><span class="code-snippet_outer">    v10 = <span class="code-snippet__number">4L</span>L;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">goto</span> LABEL_17;</span></code><code><span class="code-snippet_outer">  }</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">if</span> ( !(<span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">int</span>)sub_8000A578(v8, aSystemBinNst) )<span class="code-snippet__comment">// /system/bin/nst</span></span></code><code><span class="code-snippet_outer">  {</span></code><code><span class="code-snippet_outer">    v10 = <span class="code-snippet__number">8L</span>L;</span></code><code><span class="code-snippet_outer">LABEL_17:</span></code><code><span class="code-snippet_outer">    *(_QWORD *)(v6 + <span class="code-snippet__number">8L</span>L * *(_QWORD *)(CRED_FLAGS_OFFSET + <span class="code-snippet__number">104</span>)) |= v10;</span></code><code><span class="code-snippet_outer">  }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">inline</span> <span class="code-snippet__keyword">int</span> <span class="code-snippet__title">kdp_restrict_fork</span><span class="code-snippet__params">(struct filename *path)</span></span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">cred</span> *<span class="code-snippet__title">shellcred</span>;</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">const</span> <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">cred_kdp</span> *<span class="code-snippet__title">cred_kdp</span> = (<span class="code-snippet__title">const</span> <span class="code-snippet__title">struct</span> <span class="code-snippet__title">cred_kdp</span> *)(<span class="code-snippet__title">current</span>-&gt;<span class="code-snippet__title">cred</span>);</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (!<span class="code-snippet__built_in">strcmp</span>(path-&gt;name, <span class="code-snippet__string">&#34;/system/bin/patchoat&#34;</span>) ||</span></code><code><span class="code-snippet_outer">                !<span class="code-snippet__built_in">strcmp</span>(path-&gt;name, <span class="code-snippet__string">&#34;/system/bin/idmap2&#34;</span>)) {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">return</span> <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> ((cred_kdp-&gt;type) &gt;&gt; <span class="code-snippet__number">1</span> &amp; <span class="code-snippet__number">1</span>) {</span></code><code><span class="code-snippet_outer">                shellcred = prepare_creds();</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> (!shellcred)</span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">return</span> <span class="code-snippet__number">1</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">                shellcred-&gt;uid.val = <span class="code-snippet__number">2000</span>;</span></code><code><span class="code-snippet_outer">                shellcred-&gt;gid.val = <span class="code-snippet__number">2000</span>;</span></code><code><span class="code-snippet_outer">                shellcred-&gt;euid.val = <span class="code-snippet__number">2000</span>;</span></code><code><span class="code-snippet_outer">                shellcred-&gt;egid.val = <span class="code-snippet__number">2000</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">                commit_creds(shellcred);</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">    kdp_restrict_fork</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">先判断二进制是否在白名单内：</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li></ul><pre class="code-snippet__js" data-lang="perl"><code><span class="code-snippet_outer">/<span class="code-snippet__keyword">system</span>/bin/patchoat</span></code><code><span class="code-snippet_outer">/<span class="code-snippet__keyword">system</span>/bin/idmap2</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  如果</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">cred_kdp-&gt;type</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">的第</span><span style="font-family:Calibri;">2</span><span style="font-family:宋体;">个</span><span style="font-family:Calibri;">bit</span><span style="font-family:宋体;">被置位， 则强制二进制程序的</span><span style="font-family:Calibri;">uid</span><span style="font-family:宋体;">为</span><span style="font-family:Calibri;">2000</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h1><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;"><span style="font-family:Calibri;">2 </span><span style="font-family:宋体;">自身防护差距分析</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;"><o:p></o:p></span></strong></h1><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    Rkp</span><span style="font-family:宋体;">在自身防护</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">上</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">有</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">一些</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">优势，可以大大增加逆向工程分析的难度。</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h2><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">2.1 </span><span style="font-family:黑体;">字符串混淆</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    Rkp</span><span style="font-family:宋体;">对输出的字符串进行了哈希计算，大大增加了逆向过程的难度。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="perl"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> ( !(unsigned <span class="code-snippet__keyword">int</span>)sub_8000140<span class="code-snippet__number">0</span>(v6) || !(unsigned <span class="code-snippet__keyword">int</span>)sub_8000140<span class="code-snippet__number">0</span>(v6 + *(unsigned <span class="code-snippet__keyword">int</span> *)CRED_FLAGS_OFFSET - <span class="code-snippet__number">1</span>) )</span></code><code><span class="code-snippet_outer">  {</span></code><code><span class="code-snippet_outer">    debug_log(<span class="code-snippet__number">76</span>LL, aRkpD5edfb8f, <span class="code-snippet__number">140</span>LL, <span class="code-snippet__string">&#34;RKP_934c3492 %lx %lx %lx&#34;</span>, v6, v6, v6);</span></code><code><span class="code-snippet_outer">    sub_80000E9C(v6);</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">return</span> debug_log(<span class="code-snippet__number">76</span>LL, aRkpD5edfb8f, <span class="code-snippet__number">536</span>LL, <span class="code-snippet__string">&#34;RKP_b1c3f061 %lx %lx %lx&#34;</span>, v6, 0LL, 0LL);</span></code><code><span class="code-snippet_outer">  }</span></code><code><span class="code-snippet_outer"><br/></span></code></pre></section><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100000165" data-ratio="0.5268518518518519" data-s="300,640" style="" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=52045272&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_png%2F4iaJia7Cvd3PDCM6QMDyJkP6ibiaT8KvkJ9kkL6CCa2rHULWUpS2QTg9UcO3B7MtRe3nrTX38t2ictvdoO9p6cqib4eA%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><h2><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">2.2 rkp cmd</span><span style="font-family:黑体;">限定使用次数</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">   Rkp</span><span style="font-family:宋体;">对特定的</span><span style="font-family:Calibri;">cmd</span><span style="font-family:宋体;">使用次数进行了限制，比如一些初始化函数只需执行一次， 这样可以防止</span><span style="font-family:Calibri;">rop/jop</span><span style="font-family:宋体;">对其进行后续重用。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">_int64 __<span class="code-snippet__function">fastcall <span class="code-snippet__title">rkp_main</span><span class="code-snippet__params">(<span class="code-snippet__keyword">unsigned</span> __int64 a1, <span class="code-snippet__keyword">unsigned</span> __int8 *a2)</span></span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> ( byte_422A8 )                            [<span class="code-snippet__number">1</span>]                      </span></code><code><span class="code-snippet_outer">      rkp_policy_violation(<span class="code-snippet__number">2u</span>, <span class="code-snippet__number">0L</span>L, <span class="code-snippet__number">0L</span>L, <span class="code-snippet__number">0L</span>L);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">      <span class="code-snippet__keyword">if</span> ( (<span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">int</span>)((__int64 (__fastcall *)(__int64))rkp_paging_init)(v21) )     [<span class="code-snippet__number">2</span>]</span></code><code><span class="code-snippet_outer">      {</span></code><code><span class="code-snippet_outer">        byte_422A8 = <span class="code-snippet__number">1</span>;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    [2]</span><span style="font-family:宋体;">处在</span><span style="font-family:Calibri;">rkp_main</span><span style="font-family:宋体;">执行完后对</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">byte_422A8</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">变量设置为</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">， 当下次</span><span style="font-family:Calibri;">rkp_main</span><span style="font-family:宋体;">再次被调用时在</span><span style="font-family:Calibri;">[1]</span><span style="font-family:宋体;">处会被执行检查， </span><span style="font-family:Calibri;">rkp_policy_violation</span><span style="font-family:宋体;">函数打印</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">”</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">Multiple INIT calls</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">”</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">并</span><span style="font-family:Calibri;">panic</span><span style="font-family:宋体;">系统。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h2><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">2.3 stack canary</span><span style="font-family:黑体;">栈溢出保护</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  三星</span><span style="font-family:Calibri;">s20</span><span style="font-family:宋体;">使用的高通</span><span style="font-family:Calibri;">qhee</span><span style="font-family:宋体;">平台使用了</span><span style="font-family:Calibri;">stack canary</span><span style="font-family:宋体;">栈溢出保护机制。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  在一些关键函数的开头插入如下代码：</span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100000166" data-ratio="0.29444444444444445" data-s="300,640" style="" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=bcea6102&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_png%2F4iaJia7Cvd3PDCM6QMDyJkP6ibiaT8KvkJ9kqEmUib8XYGR3d375lNwK0RHRPVHobl7x1Lu9UjNk1j8K3a4RuAAPiaUg%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/><span style="font-family: Calibri;font-size: 10.5pt;letter-spacing: 0.034em;text-align: justify;"></span></p><h2 style="text-indent:21.0000pt;"><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:normal;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">qword_80094A48</span><span style="font-family:宋体;">地址保存的是</span><span style="font-family:Calibri;">rkp</span><span style="font-family:宋体;">启动时产生的一个随机值，用作</span><span style="font-family:Calibri;">stack canary</span><span style="font-family:宋体;">，保存在</span><span style="font-family:Calibri;">x8</span><span style="font-family:宋体;">寄存器中。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:normal;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></h2><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  在函数的末尾插入如下代码：</span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100000167" data-ratio="0.15648148148148147" data-s="300,640" style="" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=35f54a43&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_png%2F4iaJia7Cvd3PDCM6QMDyJkP6ibiaT8KvkJ9kERMJB3DMbOpjk9KhRsNxaB6teiclZt3VrHdaFDzTTZcThYDBDtCt8yA%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;"> 重新加载</span><span style="font-family:Calibri;">qword_80094A48</span><span style="font-family:宋体;">值到</span><span style="font-family:Calibri;">x9</span><span style="font-family:宋体;">寄存器，然后与之前保存的</span><span style="font-family:Calibri;">x8</span><span style="font-family:宋体;">寄存器值进行比较，如果发生改变则跳转到</span><span style="font-family:Calibri;">loc_8000442DC</span><span style="font-family:宋体;">去执行。</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100000168" data-ratio="0.17685185185185184" data-s="300,640" style="" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=c38a1c13&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_png%2F4iaJia7Cvd3PDCM6QMDyJkP6ibiaT8KvkJ9kict0AzoaZCbVqib7dibHlkZ5HbGXxPDp8q2QDbU691IOd45iaymZhRS8wQ%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><h2><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">2.4 gadget</span><span style="font-family:黑体;">去除</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  三星、苹果在发布的</span><span style="font-family:Calibri;">binary</span><span style="font-family:宋体;">程序中，将黑客经常用到的</span><span style="font-family:Calibri;">gadget</span><span style="font-family:宋体;">优化掉， 防止</span><span style="font-family:Calibri;">rop/jop</span><span style="font-family:宋体;">利用。</span></span></p><p style="display: none;"><mp-style-type data-value="3"></mp-style-type></p>



<p><a href="2247483819">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=5c3f846a&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg4NjU1NDU4MA%3D%3D%26mid%3D2247483819%26idx%3D1%26sn%3Dd74ac929c46c49e89ec0fb69842abb1b%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Wed, 06 Mar 2024 11:46:00 +0800</pubDate>
    </item>
    <item>
      <title>IOS 16内核内存分配器安全机制分析</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg4NjU1NDU4MA==&amp;mid=2247483807&amp;idx=1&amp;sn=4480e52a6896a9b5dc37462506563bdd</link>
      <description>Ios系统的内核内存分配器是目前笔者见到的最为安全的内存分配器，没有之一。</description>
      <content:encoded><![CDATA[<p>
<span>wzt</span> <span>2024-03-03 12:25</span> <span style="display: inline-block;">上海</span>
</p>

<p>Ios系统的内核内存分配器是目前笔者见到的最为安全的内存分配器，没有之一。</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=bdb37528&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_jpg%2F4iaJia7Cvd3PA5L29tiadE6icdCCd43pialAGQIBu0EpkqBULVjk4IicYuDgewAS5SqDsmTpobOl9RjWhv5YVKGpDhJw%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<h1><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;">1、</span><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;">简述</span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;"><o:p></o:p></span></strong></h1><p>   <span style="font-size: 10.5pt;font-family: 宋体;">Ios系统的内核内存分配器是目前笔者见到的最为安全的内存分配器，没有之一。</span><br/></p><h2><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">1.1 </span><span style="font-family:黑体;">放弃</span><span style="font-family:Arial;">FIFO</span><span style="font-family:黑体;">设计</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:Arial;mso-fareast-font-family:黑体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  首先苹果公司抛弃了内存分配器的</span><span style="font-family:Calibri;">LIFO</span><span style="font-family:宋体;">这种结构设计，后进先出是栈的结构，对于刚释放的内存会优先让它分配出去，操作系统讲究程序局部性原理，也就是最近使用的内存很可能会最近再次被使用。这种设计有助于提高内存分配器的性能。但是很多漏洞攻击程序会利用这个特点，精心的控制内存布局，这几乎是每个内核堆攻击必然要使用的技巧。苹果公司为了安全直接放弃了</span><span style="font-family:Calibri;">LIFO</span><span style="font-family:宋体;">的设计</span><span style="font-family:Calibri;">, </span><span style="font-family:宋体;">我们在</span><span style="font-family:Calibri;">zalloc</span><span style="font-family:宋体;">源码中，可以见到如下注释：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100000150" data-ratio="0.27314814814814814" data-s="300,640" style="" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=6b3d6f3b&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_png%2F4iaJia7Cvd3PA5L29tiadE6icdCCd43pialAGhJcyEEibK8AKfo4bZBarGdwu9ZiamwOmcZAictlicKDbj572Oqq79kpK4g%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/><span style="font-family: Calibri;font-size: 10.5pt;letter-spacing: 0.034em;text-align: justify;"></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">我们先看下</span><span style="font-family:Calibri;">cache</span><span style="font-family:宋体;">的架构：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100000151" data-ratio="0.45092592592592595" data-s="300,640" style="" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=8d879947&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_png%2F4iaJia7Cvd3PA5L29tiadE6icdCCd43pialAGCZKfgxtiaXLfzxnL8CWicNLah0N6Vz941UUeBfRqFNZXpcwaGUBbzCBg%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  一个</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">cache</span><span style="font-family:宋体;">包含两大块结构，第一为左侧的</span><span style="font-family:Calibri;">zc_alloc</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">zc_free magazine</span><span style="font-family:宋体;">，一个专门用来分配内存，一个专门用来释放内存。右侧为</span><span style="font-family:Calibri;">cpu</span><span style="font-family:宋体;">的本地仓库</span><span style="font-family:Calibri;">depot</span><span style="font-family:宋体;">，它是一个单向链表，链接着数个空闲的</span><span style="font-family:Calibri;">magazine</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span> *</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">zalloc_cached</span><span class="code-snippet__params">(<span class="code-snippet__keyword">zone_t</span> zone, <span class="code-snippet__keyword">zone_stats_t</span> zstats, <span class="code-snippet__keyword">zalloc_flags_t</span> flags,</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">vm_size_t</span> esize)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">zone_cache_t</span> cache;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">cache = zpercpu_get(zone-&gt;z_pcpu_cache);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> (cache-&gt;zc_alloc_cur == <span class="code-snippet__number">0</span>) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> (__improbable(cache-&gt;zc_free_cur == <span class="code-snippet__number">0</span>)) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">return</span> zalloc_cached_slow(zone, zstats, flags, esize, cache);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_cache_swap_magazines(cache);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">return</span> zalloc_cached_fast(zone, zstats, flags, esize, cache, <span class="code-snippet__literal">NULL</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  首先判断</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">zc_allo</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">这个</span><span style="font-family:Calibri;">magazine</span><span style="font-family:宋体;">是否为空，不为空就从这里划走一个</span><span style="font-family:Calibri;">element</span><span style="font-family:宋体;">。如果为空，则会判断</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">zc_</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">free</span><span style="font-family:宋体;">这个</span><span style="font-family:Calibri;">magazine</span><span style="font-family:宋体;">，如果它不为空，就将它们俩进行交换。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="php"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">static</span> void</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_cache_swap_magazines(zone_cache_t cache)</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">uint16_t count_a = cache-&gt;zc_alloc_cur;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">uint16_t count_f = cache-&gt;zc_free_cur;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_element_t *elems_a = cache-&gt;zc_alloc_elems;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_element_t *elems_f = cache-&gt;zc_free_elems;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">z_debug_assert(count_a &lt;= zc_mag_size());</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">z_debug_assert(count_f &lt;= zc_mag_size());</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">cache-&gt;zc_alloc_cur = count_f;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">cache-&gt;zc_free_cur = count_a;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">cache-&gt;zc_alloc_elems = elems_f;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">cache-&gt;zc_free_elems = elems_a;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style="margin-left: 21pt;"><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">只对指针和对应</span><span style="font-family:Calibri;">element</span><span style="font-family:宋体;">数据进行了交换。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style="margin-left: 21pt;"><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">在看下</span><span style="font-family:Calibri;">cache free</span><span style="font-family:宋体;">的过程：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span></span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">zfree_cached</span><span class="code-snippet__params">(<span class="code-snippet__keyword">zone_t</span> zone, struct zone_page_metadata *meta, <span class="code-snippet__keyword">zone_element_t</span> ze)</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">zone_cache_t</span> cache = zpercpu_get(zone-&gt;z_pcpu_cache);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> (cache-&gt;zc_free_cur &gt;= zc_mag_size()) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> (cache-&gt;zc_alloc_cur &gt;= zc_mag_size()) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">return</span> zfree_cached_slow(zone, meta, ze, cache);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_cache_swap_magazines(cache);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">uint16_t</span> idx = cache-&gt;zc_free_cur++;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> (idx &gt;= zc_mag_size()) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_accounting_panic(zone, <span class="code-snippet__string">&#34;zc_free_cur overflow&#34;</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">cache-&gt;zc_free_elems[idx] = ze;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  如果</span><span style="font-family:Calibri;">zc_free</span><span style="font-family:宋体;">保存的</span><span style="font-family:Calibri;">element</span><span style="font-family:宋体;">过多，则调用</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">zone_cache_swap_magazines</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">zc_alloc</span><span style="font-family:宋体;">进行交换，否则放回</span><span style="font-family:Calibri;">zc_free magazine</span><span style="font-family:宋体;">里。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  分配内存时，直接从</span><span style="font-family:Calibri;">zc_alloc</span><span style="font-family:宋体;">里分配， 释放时一直会放回</span><span style="font-family:Calibri;">zc_free magzine</span><span style="font-family:宋体;">里，可以说分配和释放几乎避开了</span><span style="font-family:Calibri;">FIFO</span><span style="font-family:宋体;">的特性，相互不打扰。但是为什么说是几乎呢，因为逻辑中还有</span><span style="font-family:Calibri;">swap</span><span style="font-family:宋体;">两个</span><span style="font-family:Calibri;">magazione</span><span style="font-family:宋体;">的情景，但是对于漏洞利用来讲也会增加不少难度。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h2><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">1.2 meta</span><span style="font-family:黑体;">和</span><span style="font-family:Arial;">element</span><span style="font-family:黑体;">分离设计</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><h3><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">1.2.1 bsd</span><span style="font-family:宋体;">与</span><span style="font-family:Calibri;">linux</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h3><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  除了</span><span style="font-family:Calibri;">windows</span><span style="font-family:宋体;">，其他几大操作系统内核</span><span style="font-family:Calibri;">bsd</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">linux</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">xnu</span><span style="font-family:宋体;">都使用基于</span><span style="font-family:Calibri;">solaris slab</span><span style="font-family:宋体;">的结构设计。对于一个</span><span style="font-family:Calibri;">chunk</span><span style="font-family:宋体;">，它的管理结构</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">chunk</span><span style="font-family:宋体;">里的</span><span style="font-family:Calibri;">element</span><span style="font-family:宋体;">在设计上，每个</span><span style="font-family:Calibri;">os</span><span style="font-family:宋体;">却不一样，对于</span><span style="font-family:Calibri;">bsd</span><span style="font-family:宋体;">来讲，它的设计是最糟糕的，</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">管理结构直接放在了</span><span style="font-family:Calibri;">element</span><span style="font-family:宋体;">的后面：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100000152" data-ratio="0.8455200823892894" data-s="300,640" style="" data-type="png" data-w="971" src="https://wechat2rss.xlab.app/img-proxy/?k=2e18c846&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_png%2F4iaJia7Cvd3PA5L29tiadE6icdCCd43pialAGFxicu3DHouxQaBtzLOibfqCY8XSibHveblaquu4X9aLP8FljBLWb3EXzA%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  对于小块</span><span style="font-family:Calibri;">item</span><span style="font-family:宋体;">， </span><span style="font-family:Calibri;">slab</span><span style="font-family:宋体;">这种设计属于严重的安全错误设计，</span><span style="font-family:Calibri;">slab header</span><span style="font-family:宋体;">放在所有</span><span style="font-family:Calibri;">item</span><span style="font-family:宋体;">的最后，如果最后一个</span><span style="font-family:Calibri;">item</span><span style="font-family:宋体;">发生溢出，就可以直接覆盖</span><span style="font-family:Calibri;">slab header</span><span style="font-family:宋体;">里的数据结构。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">uma_slab</span> {</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">uma_keg_t</span>       us_keg;                 <span class="code-snippet__comment">/* Keg we live in */</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">...</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">Slab header结构为<span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">Uma_slab</span>，它的第一个成员是<span class="code-snippet__title">us_keg</span>。</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">struct</span> <span class="code-snippet__title">uma_keg</span> {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">LIST_HEAD(,uma_zone)    uk_zones;       <span class="code-snippet__comment">/* Keg&#39;s zones */</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">...</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">  Uk_zones</span><span style="font-family:宋体;">结构为：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">uma_zone</span> {</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">uma_ctor        uz_ctor;        <span class="code-snippet__comment">/* Constructor for each allocation */</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">uma_dtor        uz_dtor;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  结构体成员</span><span style="font-family:Calibri;">uz_ctor</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">uz_dtor</span><span style="font-family:宋体;">为每个</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">在创建和销毁时调用的析构函数指针，</span><span style="font-family:Calibri;">exploit</span><span style="font-family:宋体;">程序一般都会替换这两个函数指针，使其指向</span><span style="font-family:Calibri;">shellcode</span><span style="font-family:宋体;">地址。</span><span style="font-family:Calibri;">Slab header</span><span style="font-family:宋体;">放在最后，使堆溢出攻击变得更加简单。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  而因为</span><span style="font-family:Calibri;">linux</span><span style="font-family:宋体;">内核则对基进行了改进，把</span><span style="font-family:Calibri;">slab header</span><span style="font-family:宋体;">放在了最前面。我们在设计内存分配器时就要避免这种糟糕的设计，同时管理结构体中函数指针的定义一定要做到最少，防止被</span><span style="font-family:Calibri;">exploit</span><span style="font-family:宋体;">程序滥用。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h3><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">1.2.2 xnu</span><span style="font-family:宋体;">的分离设计</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h3><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    Xnu</span><span style="font-family:宋体;">在</span><span style="font-family:Calibri;">8000</span><span style="font-family:宋体;">版本中，将</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">与</span><span style="font-family:Calibri;">element</span><span style="font-family:宋体;">做了分离设计：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100000153" data-ratio="0.7583333333333333" data-s="300,640" style="" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=d8548f78&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_png%2F4iaJia7Cvd3PA5L29tiadE6icdCCd43pialAGoAx9ZVPbiaianPU9RwQfiaOMORpIfCj6fy8l1Mpsag1CgnhN7bmtYaRibQ%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  一个</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">的基本管理结构为</span><span style="font-family:Calibri;">struct zone_page_meta</span><span style="font-family:宋体;">：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">zone_page_metadata</span> {</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">union</span> {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> {</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">zone_id_t</span>       zm_index : <span class="code-snippet__number">10</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">uint16_t</span>        zm_guarded : <span class="code-snippet__number">1</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">uint16_t</span>        zm_inline_bitmap : <span class="code-snippet__number">1</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">zm_len_t</span>        zm_chunk_len : <span class="code-snippet__number">4</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">};</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">uint16_t</span> zm_bits;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">};</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">union</span> {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">define</span> ZM_ALLOC_SIZE_LOCK 1u</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">uint16_t</span> zm_alloc_size; <span class="code-snippet__comment">/* first page only */</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> {</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">uint8_t</span> zm_page_index;   <span class="code-snippet__comment">/* secondary pages only */</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">uint8_t</span> zm_subchunk_len; <span class="code-snippet__comment">/* secondary pages only */</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">};</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">uint16_t</span> zm_oob_offs;   <span class="code-snippet__comment">/* in guard pages  */</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">};</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">union</span> {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">uint32_t</span> zm_bitmap;     <span class="code-snippet__comment">/* most zones      */</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">uint32_t</span> zm_bump;       <span class="code-snippet__comment">/* permanent zones */</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">};</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">union</span> {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> {</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">zone_pva_t</span>      zm_page_next;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">zone_pva_t</span>      zm_page_prev;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">};</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">vm_offset_t</span> zm_pgz_orig_addr;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">zone_page_metadata</span> *<span class="code-snippet__title">zm_pgz_slot_next</span>;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">};</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">};</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  一个</span><span style="font-family:Calibri;">struct zone_page_metadata</span><span style="font-family:宋体;">管理一个</span><span style="font-family:Calibri;">PAGE_SIZE</span><span style="font-family:宋体;">大小的虚拟内存。内存子系统在初始化时会申请一块足够大的内存用来管理所有的物理内存。每个</span><span style="font-family:Calibri;">page_metadata</span><span style="font-family:宋体;">通过双向链表链接起来。我们看到前面</span><span style="font-family:Calibri;">cache</span><span style="font-family:宋体;">中的</span><span style="font-family:Calibri;">magazione</span><span style="font-family:宋体;">结构体保存的</span><span style="font-family:Calibri;">elements</span><span style="font-family:宋体;">就是从</span><span style="font-family:Calibri;">metadata</span><span style="font-family:宋体;">里分配的。一个虚拟地址</span><span style="font-family:Calibri;">vaddr</span><span style="font-family:宋体;">右移</span><span style="font-family:Calibri;">PAGE_SIZE</span><span style="font-family:宋体;">即可得到</span><span style="font-family:Calibri;">metadata</span><span style="font-family:宋体;">数组的索引。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  每个</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">又挂接在</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">的几个队列里：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">zone_pva_t</span> z_pageq_empty;  <span class="code-snippet__comment">/* populated, completely empty pages   */</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">zone_pva_t</span> z_pageq_partial;<span class="code-snippet__comment">/* populated, partially filled pages   */</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">zone_pva_t</span> z_pageq_full;   <span class="code-snippet__comment">/* populated, completely full pages    */</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">zone_pva_t</span> z_pageq_va;     <span class="code-snippet__comment">/* non-populated VA pages              */</span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  z_pageq_empty</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">为空队列，</span> </span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">z_pageq_partial</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">为半满队列，</span> </span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">z_pageq_full</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">为全满队列，</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">z_pageq_va</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">为备用队列。每个基于</span><span style="font-family:Calibri;">slab</span><span style="font-family:宋体;">的内存管理器都会前三个队列。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">__<span class="code-snippet__function">header_always_inline <span class="code-snippet__keyword">void</span></span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">zalloc_import</span><span class="code-snippet__params">(<span class="code-snippet__keyword">zone_t</span> zone, <span class="code-snippet__keyword">zone_element_t</span> *elems, <span class="code-snippet__keyword">zalloc_flags_t</span> flags,</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">vm_size_t</span> esize, <span class="code-snippet__keyword">uint32_t</span> n)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">do</span> {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">vm_offset_t</span> page, eidx, size = <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">zone_page_metadata</span> *<span class="code-snippet__title">meta</span>;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> (!zone_pva_is_null(zone-&gt;z_pageq_partial)) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">meta = zone_pva_to_meta(zone-&gt;z_pageq_partial);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">page = zone_pva_to_addr(zone-&gt;z_pageq_partial);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">} <span class="code-snippet__keyword">else</span> <span class="code-snippet__keyword">if</span> (!zone_pva_is_null(zone-&gt;z_pageq_empty)) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">meta = zone_pva_to_meta(zone-&gt;z_pageq_empty);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">page = zone_pva_to_addr(zone-&gt;z_pageq_empty);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_counter_sub(zone, z_wired_empty, meta-&gt;zm_chunk_len);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">} <span class="code-snippet__keyword">else</span> {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_accounting_panic(zone, <span class="code-snippet__string">&#34;z_elems_free corruption&#34;</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_meta_validate(zone, meta, page);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">vm_offset_t</span> old_size = meta-&gt;zm_alloc_size;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">vm_offset_t</span> max_size = ptoa(meta-&gt;zm_chunk_len) + ZM_ALLOC_SIZE_LOCK;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">do</span> {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">eidx = zone_meta_find_and_clear_bit(zone, meta, flags);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">elems[i++] = zone_element_encode(page, eidx);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">size += esize;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">} <span class="code-snippet__keyword">while</span> (i &lt; n &amp;&amp; old_size + size + esize &lt;= max_size);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">vm_offset_t</span> new_size = zone_meta_alloc_size_add(zone, meta, size);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> (new_size + esize &gt; max_size) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_meta_requeue(zone, &amp;zone-&gt;z_pageq_full, meta);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">} <span class="code-snippet__keyword">else</span> <span class="code-snippet__keyword">if</span> (old_size == <span class="code-snippet__number">0</span>) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">/* remove from free, move to intermediate */</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_meta_requeue(zone, &amp;zone-&gt;z_pageq_partial, meta);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">} <span class="code-snippet__keyword">while</span> (i &lt; n);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  分配内存时首先从</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">z_pageq_partial</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">半满队列分配，如果它为空，则再从</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">z_pageq_empty</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">队列分配。如果分配完后，</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">里的</span><span style="font-family:Calibri;">elements</span><span style="font-family:宋体;">用完，则挂接到</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">z_pageq_full, meta</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">全满队列，否则挂接到</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">z_pageq_partial</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">半满队列里。</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  注意每个队列的类型为</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">zone_pva_t</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">：</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">typedef</span> <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">zone_packed_virtual_address</span> {</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">uint32_t</span> packed_address;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">} <span class="code-snippet__keyword">zone_pva_t</span>;</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  它是一个</span><span style="font-family:Calibri;">32</span><span style="font-family:宋体;">字节的结构体，保存的是</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">的索引。每个队列的</span><span style="font-family:Calibri;">header</span><span style="font-family:宋体;">是放在内核</span><span style="font-family:Calibri;">__DATA section</span><span style="font-family:宋体;">里。</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100000154" data-ratio="0.38055555555555554" data-s="300,640" style="" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=8ad0a71f&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_png%2F4iaJia7Cvd3PA5L29tiadE6icdCCd43pialAGztXoHWFpUTajJTZoMax9thggKWw26Fr5KmXHPQus6Ll9CRRj37yZIw%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/><span style="font-family: Calibri;font-size: 10.5pt;letter-spacing: 0.034em;text-align: justify;"></span></p><p style="margin-left: 21pt;"><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">队列</span><span style="font-family:Calibri;">header</span><span style="font-family:宋体;">指向第一个</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">，每个</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">有通过双向链表链接起来。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">__<span class="code-snippet__function">header_always_inline <span class="code-snippet__keyword">void</span></span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">zone_meta_queue_push</span><span class="code-snippet__params">(<span class="code-snippet__keyword">zone_t</span> z, <span class="code-snippet__keyword">zone_pva_t</span> *headp,</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">struct zone_page_metadata *meta)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">zone_pva_t</span> head = *headp;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">zone_pva_t</span> queue_pva = zone_queue_encode(headp);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">zone_page_metadata</span> *<span class="code-snippet__title">tmp</span>;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">meta-&gt;zm_page_next = head;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> (!zone_pva_is_null(head)) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">tmp = zone_pva_to_meta(head);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> (!zone_pva_is_equal(tmp-&gt;zm_page_prev, queue_pva)) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_page_metadata_list_corruption(z, meta);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">tmp-&gt;zm_page_prev = zone_pva_from_meta(meta);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">meta-&gt;zm_page_prev = queue_pva;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">*headp = zone_pva_from_meta(meta);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  通过</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">zone_meta_queue_push</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">将一个</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">挂接到队列里。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">__<span class="code-snippet__function">header_always_inline struct zone_page_metadata *</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">zone_meta_queue_pop</span><span class="code-snippet__params">(<span class="code-snippet__keyword">zone_t</span> z, <span class="code-snippet__keyword">zone_pva_t</span> *headp)</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">zone_pva_t</span> head = *headp;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">zone_page_metadata</span> *<span class="code-snippet__title">meta</span> = <span class="code-snippet__title">zone_pva_to_meta</span>(<span class="code-snippet__title">head</span>);</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">zone_page_metadata</span> *<span class="code-snippet__title">tmp</span>;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_meta_validate(z, meta);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> (!zone_pva_is_null(meta-&gt;zm_page_next)) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">tmp = zone_pva_to_meta(meta-&gt;zm_page_next);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> (!zone_pva_is_equal(tmp-&gt;zm_page_prev, head)) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_page_metadata_list_corruption(z, meta);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">tmp-&gt;zm_page_prev = meta-&gt;zm_page_prev;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">*headp = meta-&gt;zm_page_next;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">meta-&gt;zm_page_next = meta-&gt;zm_page_prev = (<span class="code-snippet__keyword">zone_pva_t</span>){ <span class="code-snippet__number">0</span> };</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">return</span> meta;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  通过</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">zone_meta_queue_pop</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">将</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">移出队列。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  我们看到</span><span style="font-family:Calibri;">xnu</span><span style="font-family:宋体;">通过这种精妙的设计彻底将</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">与</span><span style="font-family:Calibri;">element</span><span style="font-family:宋体;">分离出来，能有效的提高攻击难度。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h2><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">1.3 </span><span style="font-family:黑体;">有趣的</span><span style="font-family:Arial;">Guard page</span><span style="font-family:黑体;">设计</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  几乎每个内存管理器都会有</span><span style="font-family:Calibri;">Guard page</span><span style="font-family:宋体;">，而</span><span style="font-family:Calibri;">xnu</span><span style="font-family:宋体;">的设计更加有趣。本来申请一个</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">后会返回它的虚拟地址，但是</span><span style="font-family:Calibri;">xnu</span><span style="font-family:宋体;">会在另一个区域里分配两个连续的</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">，它会概率性的在这个</span><span style="font-family:Calibri;">Meta</span><span style="font-family:宋体;">后面加入一个</span><span style="font-family:Calibri;">guard page</span><span style="font-family:宋体;">，这个</span><span style="font-family:Calibri;">page</span><span style="font-family:宋体;">只有虚拟内存，没有映射对应的物理内存，因此一旦</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">溢出，就会发生</span><span style="font-family:Calibri;">page fault</span><span style="font-family:宋体;">。而前面的</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">将虚拟地址映射为原先申请的</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">的物理地址，也就是</span><span style="font-family:Calibri;">double mapping</span><span style="font-family:宋体;">，然后将新的</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">地址返回。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">先看下它的架构：</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100000155" data-ratio="0.5657407407407408" data-s="300,640" style="" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=2bb1101b&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_png%2F4iaJia7Cvd3PA5L29tiadE6icdCCd43pialAGUtdgVm7ImuEt8aEh3uxn3cH1PJK2ic2qFe9jhqab8dkdh6PfmJsiaQYw%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  内存子系统在初始化时会从</span><span style="font-family:Calibri;">meta_base</span><span style="font-family:宋体;">里划出一块内存，用作有</span><span style="font-family:Calibri;">guard page</span><span style="font-family:宋体;">需求的</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">pgz_init(<span class="code-snippet__keyword">void</span>)</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">for</span> (<span class="code-snippet__keyword">size_t</span> i = <span class="code-snippet__number">0</span>; i &lt; <span class="code-snippet__number">2</span> * pgz_slots + <span class="code-snippet__number">1</span>; i += <span class="code-snippet__number">2</span>) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_info.zi_pgz_meta[i].zm_chunk_len = ZM_PGZ_GUARD;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">for</span> (<span class="code-snippet__keyword">size_t</span> i = <span class="code-snippet__number">1</span>; i &lt; pgz_slots; i++) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_info.zi_pgz_meta[<span class="code-snippet__number">2</span> * i - <span class="code-snippet__number">1</span>].zm_pgz_slot_next =</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    &amp;zone_info.zi_pgz_meta[<span class="code-snippet__number">2</span> * i + <span class="code-snippet__number">1</span>];</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">for</span> (<span class="code-snippet__keyword">uint32_t</span> slot = <span class="code-snippet__number">0</span>; slot &lt; pgz_slots; slot++) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">(<span class="code-snippet__keyword">void</span>)pmap_enter_options_addr(kernel_pmap, pgz_addr(slot), <span class="code-snippet__number">0</span>,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    VM_PROT_NONE, VM_PROT_NONE, <span class="code-snippet__number">0</span>, FALSE,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    PMAP_OPTIONS_NOENTER, <span class="code-snippet__literal">NULL</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  注意上述函数将</span><span style="font-family:Calibri;">slot</span><span style="font-family:宋体;">的虚拟地址暂时都映射到物理地址</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">上。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  在内存分配时，调用</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">pgz_protect</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">实施前述的</span><span style="font-family:Calibri;">guard</span><span style="font-family:宋体;">保护。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">__attribute__((noinline))</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">static</span> vm_offset_t</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">pgz_protect</span><span class="code-snippet__params">(<span class="code-snippet__keyword">zone_t</span> zone, <span class="code-snippet__keyword">vm_offset_t</span> addr, <span class="code-snippet__keyword">zalloc_flags_t</span> flags, <span class="code-snippet__keyword">void</span> *fp)</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">kern_return_t</span> kr;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">uint32_t</span> slot;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> (!pgz_slot_alloc(&amp;slot)) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">return</span> addr;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">vm_offset_t</span>  new_addr = pgz_addr(slot);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">pmap_paddr_t</span> pa = kvtophys(trunc_page(addr));</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">kr = pmap_enter_options_addr(kernel_pmap, new_addr, pa,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    VM_PROT_READ | VM_PROT_WRITE, VM_PROT_NONE, <span class="code-snippet__number">0</span>, TRUE,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    (flags &amp; Z_NOWAIT) ? PMAP_OPTIONS_NOWAIT : <span class="code-snippet__number">0</span>, <span class="code-snippet__literal">NULL</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> (__improbable(kr != KERN_SUCCESS)) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">pgz_slot_free(slot);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">return</span> addr;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">zone_page_metadata</span> <span class="code-snippet__title">tmp</span> = {</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">.zm_chunk_len = ZM_PGZ_ALLOCATED,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">.zm_index     = zone_index(zone),</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">};</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">zone_page_metadata</span> *<span class="code-snippet__title">meta</span> = <span class="code-snippet__title">pgz_meta</span>(<span class="code-snippet__title">slot</span>);</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">os_atomic_store(&amp;meta-&gt;zm_bits, tmp.zm_bits, relaxed);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">os_atomic_store(&amp;meta-&gt;zm_pgz_orig_addr, addr, relaxed);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">pgz_backtrace(pgz_bt(slot, <span class="code-snippet__literal">false</span>), fp);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">return</span> new_addr + (addr &amp; PAGE_MASK);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">   pgz_slot_alloc</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">函数从</span><span style="font-family:Calibri;">zi_pgz_meta</span><span style="font-family:宋体;">里选取一个</span><span style="font-family:Calibri;">slot</span><span style="font-family:宋体;">，一个</span><span style="font-family:Calibri;">slot</span><span style="font-family:宋体;">是由两个</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">组成。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"> pgz_addr</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">函数从这个</span><span style="font-family:Calibri;">slot</span><span style="font-family:宋体;">中提取新的虚拟地址，</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">kvtophys</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">函数从老的虚拟机地址里提取对应的物理地址，</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">pmap_enter_options_addr</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">将新的虚拟地址重新映射到刚才提取到的物理地址中，形成了一个双映射。而后面的</span><span style="font-family:Calibri;">guard page</span><span style="font-family:宋体;">虽然由虚拟地址，但是没有映射到对应的物理地址上，因此访问</span><span style="font-family:Calibri;">guard</span><span style="font-family:宋体;">内的内存就会产生</span><span style="font-family:Calibri;">page fault</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  注：</span><span style="font-family:Calibri;">ios16 beta</span><span style="font-family:宋体;">并没有开启此保护。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h2><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">1.4 Readonly</span><span style="font-family:黑体;">保护</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    Zone</span><span style="font-family:宋体;">提供了一个只读内存的功能，当一些数据在初始化后，基本就不会在改变的时候，就可以将其放入</span><span style="font-family:Calibri;">readonly</span><span style="font-family:宋体;">内存区域，然后通过</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">进行写保护。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    Zone</span><span style="font-family:宋体;">提供了</span><span style="font-family:Calibri;">3</span><span style="font-family:宋体;">个接口用于操作只读内存。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h3><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">1.4.1 </span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;">zalloc_ro_mut</span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h3><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">__attribute__((noinline))</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">void</span></span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">zalloc_ro_mut</span><span class="code-snippet__params">(<span class="code-snippet__keyword">zone_id_t</span> zid, <span class="code-snippet__keyword">void</span> *elem, <span class="code-snippet__keyword">vm_offset_t</span> offset,</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">const</span> <span class="code-snippet__keyword">void</span> *new_data, <span class="code-snippet__keyword">vm_size_t</span> new_data_size)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zalloc_ro_mut_validate_src(zid, elem, (<span class="code-snippet__keyword">vm_offset_t</span>)new_data,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    new_data_size);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">pmap_ro_zone_memcpy(zid, (<span class="code-snippet__keyword">vm_offset_t</span>) elem, offset,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    (<span class="code-snippet__keyword">vm_offset_t</span>) new_data, new_data_size);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  zalloc_ro_mut</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">函数用于将指定内存拷贝到只读内存，</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">pmap_ro_zone_memcpy</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">函数请求的是</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">中对应的服务函数， 我们以最新的</span><span style="font-family:Calibri;">ios16</span><span style="font-family:宋体;">为例进行逆向分析。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="properties"><code><span class="code-snippet_outer"><span class="code-snippet__attr">pmap_ro_zone_memcpy_ppl</span> <span class="code-snippet__string">; DATA XREF:</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">MOV</span> <span class="code-snippet__string">X20, X4</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">MOV</span> <span class="code-snippet__string">X22, X3</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">MOV</span> <span class="code-snippet__string">X23, X2</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">MOV</span> <span class="code-snippet__string">X21, X1</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">MOV</span> <span class="code-snippet__string">X25, X0</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">ADD</span> <span class="code-snippet__string">X24, X2, X1</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">MOV</span> <span class="code-snippet__string">X0, X24 ; va + offset</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">BL</span> <span class="code-snippet__string">kvtophys_nofail</span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  首先调用</span><span style="font-family:Calibri;">kvtophys_nofail</span><span style="font-family:宋体;">将</span><span style="font-family:Calibri;">va + offset</span><span style="font-family:宋体;">转为物理地址</span><span style="font-family:Calibri;">pa</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">MOV</span>             <span class="code-snippet__selector-tag">X19</span>, <span class="code-snippet__selector-tag">X0</span> ; <span class="code-snippet__selector-tag">pa</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">ADRP</span> <span class="code-snippet__selector-tag">X8</span>, <span class="code-snippet__selector-id">#vm_first_phys</span>@<span class="code-snippet__keyword">PAGE</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">LDR</span> <span class="code-snippet__selector-tag">X8</span>, <span class="code-snippet__selector-attr">[X8,#vm_first_phys@PAGEOFF]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">ADRP</span> <span class="code-snippet__selector-tag">X9</span>, <span class="code-snippet__selector-id">#vm_last_phys</span>@<span class="code-snippet__keyword">PAGE</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">LDR</span> <span class="code-snippet__selector-tag">X9</span>, <span class="code-snippet__selector-attr">[X9,#vm_last_phys@PAGEOFF]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">CMP</span> <span class="code-snippet__selector-tag">X8</span>, <span class="code-snippet__selector-tag">X0</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">CCMP</span> <span class="code-snippet__selector-tag">X9</span>, <span class="code-snippet__selector-tag">X0</span>, <span class="code-snippet__selector-id">#0</span>, <span class="code-snippet__selector-tag">LS</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">B</span><span class="code-snippet__selector-class">.LS</span> <span class="code-snippet__selector-tag">loc_FFFFFFF008498A94</span> ; <span class="code-snippet__selector-tag">vm_first_phys</span> &lt; <span class="code-snippet__selector-tag">pa</span> &lt; <span class="code-snippet__selector-tag">vm_last_phys</span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  接着判断物理地址</span><span style="font-family:Calibri;">pa</span><span style="font-family:宋体;">是否在合法地址范围内。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="nginx"><code><span class="code-snippet_outer"><span class="code-snippet__attribute">CBZ</span> X22, loc_FFFFFFF008498A78 ; <span class="code-snippet__attribute">new_data</span> == NULL</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">CBZ X20, loc_FFFFFFF008498A78 ; <span class="code-snippet__attribute">new_data_size</span> == <span class="code-snippet__number">0</span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  判断</span><span style="font-family:Calibri;">new_data</span><span style="font-family:宋体;">是否为空， </span><span style="font-family:Calibri;">new_data_size</span><span style="font-family:宋体;">是否为</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="properties"><code><span class="code-snippet_outer"><span class="code-snippet__attr">MOV</span> <span class="code-snippet__string">X0, X25</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">MOV</span> <span class="code-snippet__string">X1, X21</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">MOV</span> <span class="code-snippet__string">X2, X23</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">MOV</span> <span class="code-snippet__string">X3, X22</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">MOV</span> <span class="code-snippet__string">X4, X20</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">BL</span> <span class="code-snippet__string">pmap_ro_zone_validate_element ; (zid, va, offset, new_data, new_data_size)</span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"> 调用</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">pmap_ro_zone_validate_element</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">函数做参数检查，在稍后会详细分析。</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="properties"><code><span class="code-snippet_outer"><span class="code-snippet__attr">MOV</span> <span class="code-snippet__string">X0, X19</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">MOV</span> <span class="code-snippet__string">X1, X21</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">MOV</span> <span class="code-snippet__string">X2, X20</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">BL</span> <span class="code-snippet__string">pmap_ro_zone_lock_phy_page ; (pa, va, offset)</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">MOV</span> <span class="code-snippet__string">X0, X19 ; vm_offset_t</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">BL</span> <span class="code-snippet__string">_ml_static_ptovirt_0</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">MOV</span> <span class="code-snippet__string">X1, X22 ; __src</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">MOV</span> <span class="code-snippet__string">X2, X20 ; __n</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">BL</span> <span class="code-snippet__string">_memmove ; (pa, new_data, new_data, size)</span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  可以看到，</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">直接使用</span><span style="font-family:Calibri;">memmove</span><span style="font-family:宋体;">将目标内存拷贝进</span><span style="font-family:Calibri;">va</span><span style="font-family:宋体;">对应的物理内存。</span><span style="font-family:Calibri;">Ppl</span><span style="font-family:宋体;">并没有做请求来源的验证，这导致攻击者可以利用</span><span style="font-family:Calibri;">rop</span><span style="font-family:宋体;">等技术直接调用此服务函数，将</span><span style="font-family:Calibri;">readonly</span><span style="font-family:宋体;">内存改写为其他的内容。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  接着，</span> <span style="font-family:宋体;">我们在仔细分析</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">pmap_ro_zone_validate_element</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">函数。</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="properties"><code><span class="code-snippet_outer"><span class="code-snippet__attr">pmap_ro_zone_validate_element</span> <span class="code-snippet__string">; CODE XREF: pmap_ro_zone_bzero_ppl+6C↑p</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">ADDS</span> <span class="code-snippet__string">X8, X3, X4</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">B.CS</span> <span class="code-snippet__string">loc_FFFFFFF0084946E0 ; new_data + new_data_size &lt; new_data</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">MOV</span> <span class="code-snippet__string">X3, X4</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">B</span> <span class="code-snippet__string">pmap_ro_zone_validate_element_dst ; (zid, va, offset, new_data_size)</span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"> 首先判断</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">new_data + new_data_size</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">是否溢出，然后调用</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">pmap_ro_zone_validate_element_dst</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">。</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="nginx"><code><span class="code-snippet_outer"><span class="code-snippet__attribute">pmap_ro_zone_validate_element_dst</span> ; <span class="code-snippet__attribute">CODE</span> XREF:</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">ADRL X9, zone_ro_elem_size</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">ADD X8, X9, W0,UXTW<span class="code-snippet__comment">#3</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">LDR W8, [X8,<span class="code-snippet__comment">#4] ; elem_size = zone_ro_elem_size[zid]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">ADRL X10, zone_info.zi_ro_range</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">ADD X11, X10, <span class="code-snippet__comment">#8</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">LDP X10, X11, [X10] ; <span class="code-snippet__attribute">x10</span> = start</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">; <span class="code-snippet__attribute">x11</span> = end</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">CMP X10, X1</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">CCMP X11, X1, <span class="code-snippet__comment">#0, LS</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">B.LS            loc_FFFFFFF008494928 ; <span class="code-snippet__attribute">x10</span> &lt; va &lt; x11</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  判断</span><span style="font-family:Calibri;">va</span><span style="font-family:宋体;">是否在合法地址范围内，</span><span style="font-family:Calibri;">Readonly</span><span style="font-family:宋体;">内存是从</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">zone_info.zi_ro_range</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">专有内存块分配的。</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="nginx"><code><span class="code-snippet_outer"><span class="code-snippet__attribute">MOV</span> W10, W0</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">LSL X10, X10, <span class="code-snippet__comment">#3</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">LDR W9, [X9,X10] ; <span class="code-snippet__attribute">elem_size1</span> = zone_ro_elem_size[zid &lt;&lt; <span class="code-snippet__number">3</span>]</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">AND W10, W1, <span class="code-snippet__comment">#0x3FFF ; va &amp;= 0x3fff</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">MOV W11, <span class="code-snippet__comment">#0x4000</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">SUB W10, W11, W10 ; <span class="code-snippet__attribute">va</span> = 0x4000 - va</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">MUL W10, W9, W10 ; <span class="code-snippet__attribute">va</span> *= elem_size1</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">CMP W10, W9</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">C.CS            loc_FFFFFFF008494928 ; <span class="code-snippet__attribute">va</span> &gt; elem_size1</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  判断</span><span style="font-family:Calibri;">va</span><span style="font-family:宋体;">是否跨</span><span style="font-family:Calibri;">page</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="php"><code><span class="code-snippet_outer">UBFX X9, X1, <span class="code-snippet__comment">#0xE, #0x20 ; &#39; &#39; ; index = (uint43_t)(va &gt;&gt; 0xe)</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">ADRP X10, <span class="code-snippet__comment">#qword_FFFFFFF0077ED1D0@PAGE ; zone_info.zi_meta_base</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">LDR X10, [X10,<span class="code-snippet__comment">#qword_FFFFFFF0077ED1D0@PAGEOFF]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">LSL X9, X9, <span class="code-snippet__comment">#4</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">LDRH W9, [X10,X9]</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">AND</span> W9, W9, <span class="code-snippet__comment">#0x3FF ; zm_index = (zone_info.zi_meta_base[index &lt;&lt; 4] &amp; 0x3ff)</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">CMP W9, W0</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">B.NE            loc_FFFFFFF008494928 ; meta-&gt;zm_index != zid</span></code></pre></section><p style="margin-left:21.0000pt;mso-para-margin-left:0.0000gd;"><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">判断</span><span style="font-family:Calibri;">va</span><span style="font-family:宋体;">对应的</span><span style="font-family:Calibri;">Meta</span><span style="font-family:宋体;">指向的</span><span style="font-family:Calibri;">zm_index</span><span style="font-family:宋体;">是否与参数</span><span style="font-family:Calibri;">zid</span><span style="font-family:宋体;">相等。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="nginx"><code><span class="code-snippet_outer"><span class="code-snippet__attribute">SUB</span> X9, X8, X2</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">CMP X9, X3</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">C.CC            loc_FFFFFFF0084948D0 ; <span class="code-snippet__attribute">elem_size</span> - offset &gt; new_data_size</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">CMP X8, X2</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">B.LS loc_FFFFFFF0084948FC ; <span class="code-snippet__attribute">elem_size</span> &lt; offset</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">LDP X29, X30, [SP,<span class="code-snippet__comment">#0x30+var_s0]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">ADD SP, SP, <span class="code-snippet__comment">#0x40 ; &#39;@&#39;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">RETAB</span></code></pre></section><h3><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">1.4.2 </span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;">zalloc_ro_mut_atomic</span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h3><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">__attribute__((noinline))</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">uint64_t</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zalloc_ro_mut_atomic(<span class="code-snippet__keyword">zone_id_t</span> zid, <span class="code-snippet__keyword">void</span> *elem, <span class="code-snippet__keyword">vm_offset_t</span> offset,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">zro_atomic_op_t</span> op, <span class="code-snippet__keyword">uint64_t</span> value)</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">value = pmap_ro_zone_atomic_op(zid, (<span class="code-snippet__keyword">vm_offset_t</span>)elem, offset, op, value);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">return</span> value;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><h3><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">1.4.3 </span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;">zalloc_ro_clear</span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h3><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="properties"><code><span class="code-snippet_outer"><span class="code-snippet__attr">void</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">zalloc_ro_clear(zone_id_t</span> <span class="code-snippet__string">zid, void *elem, vm_offset_t offset, vm_size_t size)</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">{</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">pmap_ro_zone_bzero(zid,</span> <span class="code-snippet__string">(vm_offset_t)elem, offset, size);</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">}</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">pmap_ro_zone_bzero_ppl</span> <span class="code-snippet__string">; DATA XREF:</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">BL</span> <span class="code-snippet__string">pmap_ro_zone_validate_element ;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">MOV</span> <span class="code-snippet__string">X0, X19</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">MOV</span> <span class="code-snippet__string">X1, X21</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">MOV</span> <span class="code-snippet__string">X2, X20</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">BL</span> <span class="code-snippet__string">pmap_ro_zone_lock_phy_page</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">MOV</span> <span class="code-snippet__string">X0, X19 ; vm_offset_t</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">BL</span> <span class="code-snippet__string">_ml_static_ptovirt_0</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">MOV</span> <span class="code-snippet__string">X1, X20 ; size_t</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">BL</span> <span class="code-snippet__string">_bzero</span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  逻辑与前面类似，只是调用了</span><span style="font-family:Calibri;">bzero</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h2><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">1.5 SAD_FENG_SHUI</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  如前述，正常分配内存时</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">只会返回一个</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">结构，但是苹果公司为了增加堆</span><span style="font-family:Calibri;">elemments</span><span style="font-family:宋体;">的风水布局，大量使用了随机化技术， 对某些</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">，会概率性的生成</span><span style="font-family:Calibri;">N(&lt;64)</span><span style="font-family:宋体;">个</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">结构，对</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">进行了空间扩展，增加了漏洞利用难度。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="makefile"><code><span class="code-snippet_outer">static void</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_allocate_va_locked(zone_t z, zalloc_flags_t flags)</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">pages  = chunk_pages;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">guards = 0;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">runs   = 1;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">#if ZSECURITY_CONFIG(SAD_FENG_SHUI)</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">if (!z-&gt;z_percpu &amp;&amp; zone_submap_is_sequestered(zsflags)) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">pages = atop(ZONE_CHUNK_ALLOC_SIZE);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">runs  = (pages + chunk_pages - 1) / chunk_pages;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">runs  = zalloc_random_uniform32(1, runs + 1);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">pages = runs * chunk_pages;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">static_assert(ZONE_CHUNK_ALLOC_SIZE / 4096 &lt;= 64,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__string">&#34;make sure that `runs` will never be larger than 64&#34;</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">#endif</span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  不启用</span><span style="font-family:Calibri;">SAD_FENG_SHUI</span><span style="font-family:宋体;">时，</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">不使用</span><span style="font-family:Calibri;">guard</span><span style="font-family:宋体;">，</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">使用的</span><span style="font-family:Calibri;">chunk_page</span><span style="font-family:宋体;">不变。开启后，</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">chunk_page</span><span style="font-family:宋体;">会随机变为</span><span style="font-family:Calibri;">N</span><span style="font-family:宋体;">倍大小，</span><span style="font-family:Calibri;">runs</span><span style="font-family:宋体;">为随机生成的</span><span style="font-family:Calibri;">N</span><span style="font-family:宋体;">个</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">数目。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="makefile"><code><span class="code-snippet_outer"><span class="code-snippet__comment">#if ZSECURITY_CONFIG(SAD_FENG_SHUI)</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">if (z-&gt;z_percpu) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">rnum = zalloc_random_uniform32(0, 4 * 128);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">guards = rnum &gt;= 128;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">} <span class="code-snippet__keyword">else</span> if (!zsflags.z_pgz_use_guards &amp;&amp; !z-&gt;z_pgz_use_guards) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">vm_offset_t rest;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">rnum   = zalloc_random_uniform32(0, ZONE_GUARD_SPARSE);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">guards = (uint32_t)ptoa(pages) / ZONE_GUARD_SPARSE;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">rest   = (uint32_t)ptoa(pages) % ZONE_GUARD_SPARSE;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">guards += rnum &lt; rest;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">} <span class="code-snippet__keyword">else</span> if (ptoa(chunk_pages) &gt;= ZONE_GUARD_DENSE) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">rnum = zalloc_random_uniform32(65, 129);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">guards = runs * rnum / 128;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">} <span class="code-snippet__keyword">else</span> {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">vm_offset_t rest;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">rnum   = zalloc_random_uniform32(0, ZONE_GUARD_DENSE);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">guards = (uint32_t)ptoa(pages) / ZONE_GUARD_DENSE;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">rest   = (uint32_t)ptoa(pages) % ZONE_GUARD_DENSE;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">guards += rnum &lt; rest;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">assert3u(guards, &lt;=, runs);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">guard_mask = 0;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">if (!z-&gt;z_percpu &amp;&amp; zone_submap_is_sequestered(zsflags)) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">uint32_t g = 0;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">guard_mask |= 1ull &lt;&lt; (runs - 1);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">g++;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">if ((rnum &amp; 3) == 0) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">lead_guard = true;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">g++;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">if (guards &gt; g) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">guard_mask |= zalloc_random_bits(guards - g, runs - 1);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">} <span class="code-snippet__keyword">else</span> {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">guards = g;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">} <span class="code-snippet__keyword">else</span> {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">assert3u(runs, ==, 1);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">assert3u(guards, &lt;=, 1);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">guard_mask = guards &lt;&lt; (runs - 1);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  上述代码根据</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">的类型不同，概率性的判断是否要使用</span><span style="font-family:Calibri;">guard page</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="javascript"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> (lead_guard) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">meta[<span class="code-snippet__number">0</span>].zm_index = zone_index(z);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">meta[<span class="code-snippet__number">0</span>].zm_chunk_len = ZM_PGZ_GUARD;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">meta[<span class="code-snippet__number">0</span>].zm_guarded = <span class="code-snippet__literal">true</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">meta++;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  判断是否需要填入前缀</span><span style="font-family:Calibri;">guard page</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">for</span> (<span class="code-snippet__keyword">uint32_t</span> run = <span class="code-snippet__number">0</span>, n = <span class="code-snippet__number">0</span>; run &lt; runs; run++) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">bool</span> guarded = (guard_mask &gt;&gt; run) &amp; <span class="code-snippet__number">1</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">for</span> (<span class="code-snippet__keyword">uint32_t</span> i = <span class="code-snippet__number">0</span>; i &lt; chunk_pages; i++, n++) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">meta[n].zm_index = zone_index(z);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">meta[n].zm_guarded = guarded;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> (guarded) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">meta[n].zm_index = zone_index(z);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">meta[n].zm_chunk_len = ZM_PGZ_GUARD;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">n++;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style="margin-left: 21pt;"><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">循环</span><span style="font-family:Calibri;">N</span><span style="font-family:宋体;">次设置每个</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">部分结构。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> ZSECURITY_CONFIG(SAD_FENG_SHUI)</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> (__improbable(zone_caching_disabled &lt; <span class="code-snippet__number">0</span>)) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">return</span> zone_scramble_va_and_unlock(z, meta, runs, pages,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">           chunk_pages, guard_mask);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">__attribute__((noinline))</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span></span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">zone_scramble_va_and_unlock</span><span class="code-snippet__params">(</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">zone_t</span>                      z,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">struct zone_page_metadata  *meta,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">uint32_t</span>                    runs,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">uint32_t</span>                    pages,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">uint32_t</span>                    chunk_pages,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">uint64_t</span>                    guard_mask)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">zone_page_metadata</span> *<span class="code-snippet__title">arr</span>[<span class="code-snippet__title">ZONE_CHUNK_ALLOC_SIZE</span> / 4096];</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">for</span> (<span class="code-snippet__keyword">uint32_t</span> run = <span class="code-snippet__number">0</span>, n = <span class="code-snippet__number">0</span>; run &lt; runs; run++) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">arr[run] = meta + n;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">n += chunk_pages + ((guard_mask &gt;&gt; run) &amp; <span class="code-snippet__number">1</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">for</span> (<span class="code-snippet__keyword">uint32_t</span> i = runs - <span class="code-snippet__number">1</span>; i &gt; <span class="code-snippet__number">0</span>; i--) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">uint32_t</span> j = zalloc_random_uniform32(<span class="code-snippet__number">0</span>, i + <span class="code-snippet__number">1</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">meta   = arr[j];</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">arr[j] = arr[i];</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">arr[i] = meta;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_lock(z);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">for</span> (<span class="code-snippet__keyword">uint32_t</span> i = <span class="code-snippet__number">0</span>; i &lt; runs; i++) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_meta_queue_push(z, &amp;z-&gt;z_pageq_va, arr[i]);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">z-&gt;z_va_cur += z-&gt;z_percpu ? runs : pages;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">    zone_scramble_va_and_unlock</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">函数将每个</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">随机进行了置换。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;"> 经过一些列操作后，</span> <span style="font-family:宋体;">本来只会分配一个</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">， 现在会随机扩展为</span><span style="font-family:Calibri;">N</span><span style="font-family:宋体;">个</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">，第一个</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">前面可能带有</span><span style="font-family:Calibri;">guard page</span><span style="font-family:宋体;">， 随后每个</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">后面，也可能随机带有</span><span style="font-family:Calibri;">guard page</span><span style="font-family:宋体;">，并且虽有</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">都进行了随机置换。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  除此之外，每个</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">对应的</span><span style="font-family:Calibri;">element</span><span style="font-family:宋体;">前面还有一个可选的空余区域</span><span style="font-family:Calibri;">z_pgz_oob_offs</span><span style="font-family:宋体;">， 以下函数用于总一个</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">中取走一个</span><span style="font-family:Calibri;">element</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">static</span> vm_offset_t</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">zone_element_addr</span><span class="code-snippet__params">(<span class="code-snippet__keyword">zone_t</span> z, <span class="code-snippet__keyword">zone_element_t</span> ze, <span class="code-snippet__keyword">vm_offset_t</span> esize)</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">vm_offset_t</span> offs = zone_oob_offs(z);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">return</span> offs + zone_element_base(ze) + esize * zone_element_idx(ze);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">  z_pgz_oob_offs</span><span style="font-family:宋体;">是在</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">初始化时计算出来的。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">zone_t</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_create_ext(</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">const</span> <span class="code-snippet__keyword">char</span>             *name,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">vm_size_t</span>               size,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">zone_create_flags_t</span>     flags,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">zone_id_t</span>               zid,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">void</span>                  (^extra_setup)(<span class="code-snippet__keyword">zone_t</span>))</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> ZSECURITY_CONFIG(SAD_FENG_SHUI)</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> (flags &amp; ZC_PGZ_USE_GUARDS) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">z-&gt;z_pgz_oob_offs = (<span class="code-snippet__keyword">uint16_t</span>)(alloc -</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    z-&gt;z_chunk_elems * z-&gt;z_elem_size);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  实际上是把空余的区域利用起来。</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> ZSECURITY_CONFIG(PGZ_OOB_ADJUST)</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">void</span> *</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">zone_element_pgz_oob_adjust</span><span class="code-snippet__params">(struct kalloc_result kr, <span class="code-snippet__keyword">vm_size_t</span> elem_size)</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">vm_offset_t</span> addr = (<span class="code-snippet__keyword">vm_offset_t</span>)kr.addr;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">vm_offset_t</span> req_size = MAX(roundup(kr.size, KALLOC_MINALIGN), KALLOC_MINALIGN);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">vm_offset_t</span> end = addr + elem_size;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">vm_offset_t</span> offs;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> (req_size == elem_size ||</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    (end &amp; PAGE_MASK) ||</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    !zone_meta_from_addr(addr)-&gt;zm_guarded) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">return</span> kr.addr;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">offs = elem_size - req_size;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_meta_from_addr(end)-&gt;zm_oob_offs = (<span class="code-snippet__keyword">uint16_t</span>)offs;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">return</span> (<span class="code-snippet__keyword">char</span> *)addr + offs;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  zone_element_pgz_oob_adjust</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">是在</span><span style="font-family:Calibri;">kalloc_zone</span><span style="font-family:宋体;">时进行初始化。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  除了上述两个防护措施，</span> <span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">在每次从</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">中获取</span><span style="font-family:Calibri;">element</span><span style="font-family:宋体;">索引时，也使用了一定的随机化手段。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">static</span> vm_offset_t</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">zone_meta_find_and_clear_bit</span><span class="code-snippet__params">(<span class="code-snippet__keyword">zone_t</span> zone, struct zone_page_metadata *meta,</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">zalloc_flags_t</span> flags)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">zone_stats_t</span> zs = zpercpu_get(zone-&gt;z_stats);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">vm_offset_t</span> eidx = zs-&gt;zs_alloc_rr + <span class="code-snippet__number">1</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> (meta-&gt;zm_inline_bitmap) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">eidx = zba_scan_bitmap_inline(zone, meta, flags, eidx);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">} <span class="code-snippet__keyword">else</span> {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">eidx = zba_scan_bitmap_ref(zone, meta, eidx);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zs-&gt;zs_alloc_rr = (<span class="code-snippet__keyword">uint16_t</span>)eidx;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">return</span> eidx;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  zs-&gt;zs_alloc_rr</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">是通过以下函数在</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">初始化时设置。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span></span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">zone_early_scramble_rr</span><span class="code-snippet__params">(<span class="code-snippet__keyword">zone_t</span> zone, <span class="code-snippet__keyword">zone_stats_t</span> zstats)</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">int</span> cpu = cpu_number();</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">zone_stats_t</span> zs = zpercpu_get_cpu(zstats, cpu);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">uint32_t</span> bits;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">bits = random_bool_gen_bits(&amp;zone_bool_gen[cpu].zbg_bg,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    zone_bool_gen[cpu].zbg_entropy, ZONE_ENTROPY_CNT, <span class="code-snippet__number">8</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zs-&gt;zs_alloc_rr += bits;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zs-&gt;zs_alloc_rr %= zone-&gt;z_chunk_elems;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  随机生成了一个</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">到</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">z_chunk_elems</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">的索引。</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  这里也可以看到，</span> <span style="font-family:宋体;">只是在第一次分配</span><span style="font-family:Calibri;">element</span><span style="font-family:宋体;">时使用了一个随机索引，后续会在次索引后继续连续分配！</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h2><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">1.6 zone</span><span style="font-family:黑体;">不可合并</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    Linux</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">slab</span><span style="font-family:宋体;">提供了让不同数据类型，但数据大小相同的</span><span style="font-family:Calibri;">slab</span><span style="font-family:宋体;">合并一起使用。这将导致</span><span style="font-family:Calibri;">UAF</span><span style="font-family:宋体;">漏洞非常容易利用。而</span><span style="font-family:Calibri;">IOS</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">是不允许有上述合并行为的。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">static</span> zone_t</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">zone_create_find</span><span class="code-snippet__params">(</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">const</span> <span class="code-snippet__keyword">char</span>             *name,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">vm_size_t</span>               size,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">zone_create_flags_t</span>     flags,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">zone_id_t</span>              *zid_inout)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> (flags &amp; ZC_DESTRUCTIBLE) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">/*</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"> * If possible, find a previously zdestroy&#39;ed zone in the</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"> * zone_array that we can reuse.</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"> */</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">for</span> (<span class="code-snippet__keyword">int</span> i = bitmap_first(zone_destroyed_bitmap, MAX_ZONES);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    i &gt;= <span class="code-snippet__number">0</span>; i = bitmap_next(zone_destroyed_bitmap, i)) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">z = &amp;zone_array[i];</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> (<span class="code-snippet__built_in">strcmp</span>(z-&gt;z_name, name) || zone_elem_size(z) != size) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">continue</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">bitmap_clear(zone_destroyed_bitmap, i);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">z-&gt;z_destroyed = <span class="code-snippet__literal">false</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">z-&gt;z_self = z;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zid = (<span class="code-snippet__keyword">zone_id_t</span>)i;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">goto</span> out;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">    zone_create_find</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">选取之前已经分配好的一个</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">，只有名字和大小都匹配才符合条件。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h2><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">1.7 </span><span style="font-family:黑体;">无处不在的安全检查</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  在</span><span style="font-family:Calibri;">zalloc</span><span style="font-family:宋体;">内存分配器里，你会看到各种严格的参数和地址范围检查，这些检查势必带来一定的性能损耗，如果在</span><span style="font-family:Calibri;">linux</span><span style="font-family:宋体;">社区肯定会有一群人跳起来职责你。再一次，苹果公司证明安全不影响性能。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">zone_page_meta_accounting_panic(<span class="code-snippet__keyword">zone_t</span> zone, struct zone_page_metadata *meta,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">const</span> <span class="code-snippet__keyword">char</span> *kind)</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_meta_double_free_panic(<span class="code-snippet__keyword">zone_t</span> zone, <span class="code-snippet__keyword">zone_element_t</span> ze, <span class="code-snippet__keyword">const</span> <span class="code-snippet__keyword">char</span> *caller)</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_accounting_panic(<span class="code-snippet__keyword">zone_t</span> zone, <span class="code-snippet__keyword">const</span> <span class="code-snippet__keyword">char</span> *kind)</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_invalid_element_panic(<span class="code-snippet__keyword">zone_t</span> zone, <span class="code-snippet__keyword">vm_offset_t</span> addr, <span class="code-snippet__keyword">bool</span> cache)</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_element_validate(<span class="code-snippet__keyword">zone_t</span> zone, <span class="code-snippet__keyword">zone_element_t</span> ze)</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_require_panic(<span class="code-snippet__keyword">zone_t</span> zone, <span class="code-snippet__keyword">void</span> *addr)</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_id_require_panic(<span class="code-snippet__keyword">zone_id_t</span> zid, <span class="code-snippet__keyword">void</span> *addr)</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_require(<span class="code-snippet__keyword">zone_t</span> zone, <span class="code-snippet__keyword">void</span> *addr)</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_id_require(<span class="code-snippet__keyword">zone_id_t</span> zid, <span class="code-snippet__keyword">vm_size_t</span> esize, <span class="code-snippet__keyword">void</span> *addr)</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zba_chain_corruption_panic(struct zone_bits_chain *a, struct zone_bits_chain *b)</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zalloc_uaf_panic(<span class="code-snippet__keyword">zone_t</span> z, <span class="code-snippet__keyword">uintptr_t</span> elem, <span class="code-snippet__keyword">size_t</span> size)</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">panic_display_pgz_uaf_info(<span class="code-snippet__keyword">bool</span> has_syms, <span class="code-snippet__keyword">vm_offset_t</span> addr)</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zalloc_ro_mut_validation_panic</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_id_require_ro_panic</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_require_ro</span></code></pre></section><p style="display: none;"><mp-style-type data-value="3"></mp-style-type></p>



<p><a href="2247483807">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=fc96e357&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg4NjU1NDU4MA%3D%3D%26mid%3D2247483807%26idx%3D1%26sn%3D4480e52a6896a9b5dc37462506563bdd%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Sun, 03 Mar 2024 12:25:00 +0800</pubDate>
    </item>
    <item>
      <title>Windows Container逆向工程分析</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg4NjU1NDU4MA==&amp;mid=2247483796&amp;idx=1&amp;sn=07e185a325441c0570b5996edc7d408d</link>
      <description>本文基于windows10，通过逆向工程分析了内核级容器silo的完整实现原理。</description>
      <content:encoded><![CDATA[<p>
<span>wzt</span> <span>2024-03-01 12:01</span> <span style="display: inline-block;">上海</span>
</p>

<p>本文基于windows10，通过逆向工程分析了内核级容器silo的完整实现原理。</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=a2d3cd01&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_jpg%2F4iaJia7Cvd3PBZhXJuN8Sqzmg0YSmgqF2M0eibJB07PiaHdvGU3Wl9BicWGbyA2MdrWNNDCG61zzWL2YRQglu2yRVLg%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<h1><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;"><span style="font-family:Calibri;">1 </span><span style="font-family:宋体;">简介</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;"><o:p></o:p></span></strong></h1><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    windows</span><span style="font-family:宋体;">容器基于两种机制实现，一个使用虚拟化技术将</span><span style="font-family:Calibri;">container</span><span style="font-family:宋体;">放在</span><span style="font-family:Calibri;">hypvervirsor</span><span style="font-family:宋体;">中执行，另一个是使用叫做</span><span style="font-family:Calibri;">server silo</span><span style="font-family:宋体;">的技术利用内核提供的</span><span style="font-family:Calibri;">namespace</span><span style="font-family:宋体;">隔离机制。本文只分析</span><span style="font-family:Calibri;">server silo</span><span style="font-family:宋体;">的实现机制，基于</span><span style="font-family:Calibri;">win10</span><span style="font-family:宋体;">专业版</span><span style="font-family:Calibri;">10.0.19045</span><span style="font-family:宋体;">进行逆向工程分析。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h1><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;"><span style="font-family:Calibri;">2 Server silo</span><span style="font-family:宋体;">实现原理</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;"><o:p></o:p></span></strong></h1><h2><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">2.1 sdk</span><span style="font-family:黑体;">定义</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:Arial;mso-fareast-font-family:黑体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">	</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  微软公司未提供</span><span style="font-family:Calibri;">server silo</span><span style="font-family:宋体;">的用户态接口信息，内核接口可以在</span><span style="font-family:Calibri;">ntddk.h</span><span style="font-family:宋体;">中找到，这意味着微软不希望用户使用容器技术，只有微软公司自身才能使用。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">  Server silo</span><span style="font-family:宋体;">基于</span><span style="font-family:Calibri;">windows job</span><span style="font-family:宋体;">来实现，首先建立一个</span><span style="font-family:Calibri;">job object</span><span style="font-family:宋体;">，然后使用</span><span style="font-family:Calibri;">SetInformationJobObject</span><span style="font-family:宋体;">函数启动</span><span style="font-family:Calibri;">silo</span><span style="font-family:宋体;">，可以在</span><span style="font-family:Calibri;">winnt.h</span><span style="font-family:宋体;">中看到以下定义：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:新宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="makefile"><code><span class="code-snippet_outer">typedef enum _JOBOBJECTINFOCLASS {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">...</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">JobObjectCreateSilo=35,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">JobObjectSiloBasicInformation,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">JobObjectReserved15Information = 37,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">JobObjectReserved16Information = 38,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">JobObjectReserved17Information = 39,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">JobObjectReserved18Information = 40,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">JobObjectReserved19Information = 41,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">JobObjectReserved20Information = 42,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">JobObjectReserved21Information = 43,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">JobObjectReserved22Information = 44,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">JobObjectReserved23Information = 45,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">JobObjectReserved24Information = 46,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">  JobObjectReserved25Information = 47,</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">MaxJobObjectInfoClass</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">} JOBOBJECTINFOCLASS;</span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  黄色部分是</span><span style="font-family:Calibri;">silo</span><span style="font-family:宋体;">要使用的值，但是虽然在头文件中找到了</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">JobObjectSiloBasicInformation</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">的定义，但是在笔者的</span><span style="font-family:Calibri;">win10</span><span style="font-family:宋体;">专业版本的内核中并未提供此接口的实现，猜测可能在</span><span style="font-family:Calibri;">win10 server</span><span style="font-family:宋体;">中有相关实现。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="properties"><code><span class="code-snippet_outer"><span class="code-snippet__attr">typedef</span> <span class="code-snippet__string">struct _SILOOBJECT_BASIC_INFORMATION {</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">DWORD</span> <span class="code-snippet__string">SiloId;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">DWORD</span> <span class="code-snippet__string">SiloParentId;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">DWORD</span> <span class="code-snippet__string">NumberOfProcesses;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">BOOLEAN</span> <span class="code-snippet__string">IsInServerSilo;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">BYTE</span>  <span class="code-snippet__string">Reserved[3];</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">}</span> <span class="code-snippet__string">SILOOBJECT_BASIC_INFORMATION, *PSILOOBJECT_BASIC_INFORMATION;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">typedef</span> <span class="code-snippet__string">enum _SERVERSILO_STATE {</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">SERVERSILO_INITING</span> = <span class="code-snippet__string">0,</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">SERVERSILO_STARTED,</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">SERVERSILO_SHUTTING_DOWN,</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">SERVERSILO_TERMINATING,</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">SERVERSILO_TERMINATED,</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">}</span> <span class="code-snippet__string">SERVERSILO_STATE, *PSERVERSILO_STATE;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">typedef</span> <span class="code-snippet__string">struct _SERVERSILO_BASIC_INFORMATION {</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">DWORD</span> <span class="code-snippet__string">ServiceSessionId;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">SERVERSILO_STATE</span> <span class="code-snippet__string">State;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">DWORD</span>    <span class="code-snippet__string">ExitStatus;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">}</span> <span class="code-snippet__string">SERVERSILO_BASIC_INFORMATION, *PSERVERSILO_BASIC_INFORMATION;</span></span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  这个接口的相关顺序如下：</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;background:rgb(255,255,0);mso-highlight:rgb(255,255,0);">1、</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;background:rgb(255,255,0);mso-highlight:rgb(255,255,0);"><span style="font-family:宋体;">首先使用</span><span style="font-family:Calibri;">35</span><span style="font-family:宋体;">调用</span><span style="font-family:Calibri;">PspCreateSilo</span><span style="font-family:宋体;">分配一个</span><span style="font-family:Calibri;">silo storage</span><span style="font-family:宋体;">并设置</span><span style="font-family:Calibri;">silo</span><span style="font-family:宋体;">标志。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;background:rgb(255,255,0);mso-highlight:rgb(255,255,0);"><o:p></o:p></span></p><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;background:rgb(255,255,0);mso-highlight:rgb(255,255,0);">2、</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;background:rgb(255,255,0);mso-highlight:rgb(255,255,0);"><span style="font-family:宋体;">使用</span><span style="font-family:Calibri;">37</span><span style="font-family:宋体;">建立</span><span style="font-family:Calibri;">silo</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">root directory</span><span style="font-family:宋体;">和相关</span><span style="font-family:Calibri;">namespace</span><span style="font-family:宋体;">空间。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;background:rgb(255,255,0);mso-highlight:rgb(255,255,0);"><o:p></o:p></span></p><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;background:rgb(255,255,0);mso-highlight:rgb(255,255,0);">3、</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;background:rgb(255,255,0);mso-highlight:rgb(255,255,0);"><span style="font-family:宋体;">使用</span><span style="font-family:Calibri;">40</span><span style="font-family:宋体;">进一步做</span><span style="font-family:Calibri;">silo</span><span style="font-family:宋体;">的初始化。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;background:rgb(255,255,0);mso-highlight:rgb(255,255,0);"><o:p></o:p></span></p><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;background:rgb(255,255,0);mso-highlight:rgb(255,255,0);">4、</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;background:rgb(255,255,0);mso-highlight:rgb(255,255,0);"><span style="font-family:宋体;">使用</span><span style="font-family:Calibri;">41</span><span style="font-family:宋体;">结束</span><span style="font-family:Calibri;">silo</span><span style="font-family:宋体;">服务。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;background:rgb(255,255,0);mso-highlight:rgb(255,255,0);"><o:p></o:p></span></p><p><span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;background:rgb(255,255,0);mso-highlight:rgb(255,255,0);">5、</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;background:rgb(255,255,0);mso-highlight:rgb(255,255,0);"><span style="font-family:宋体;">使用</span><span style="font-family:Calibri;">47</span><span style="font-family:宋体;">控制</span><span style="font-family:Calibri;">silo</span><span style="font-family:宋体;">服务状态。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;background:rgb(255,255,0);mso-highlight:rgb(255,255,0);"><o:p></o:p></span></p><h2><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">2.2 </span><span style="font-family:黑体;">相关内核数据结构</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="diff"><code><span class="code-snippet_outer">lkd&gt; dt nt!_eprocess</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x464 BreakOnTermination : Pos 13, 1 Bit</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x510 Job              : Ptr64 _EJOB</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">lkd&gt; dt nt!_ejob</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x430 ParentJob        : Ptr64 _EJOB</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x438 RootJob          : Ptr64 _EJOB</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x4d4 JobId            : Uint4B</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x4d8 ContainerId      : _GUID</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x4e8 ContainerTelemetryId : _GUID</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x4f8 ServerSiloGlobals : Ptr64 _ESERVERSILO_GLOBALS</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x500 PropertySet      : _PS_PROPERTY_SET</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x518 Storage          : Ptr64 _PSP_STORAGE</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x528 Silo             : Pos 30, 1 Bit</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x528 ContainerTelemetryIdSet : Pos 31, 1 Bit</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x52c JobFlags2        : Uint4B</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x52c ParentLocked     : Pos 0, 1 Bit</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x52c EnableUsermodeSiloThreadImpersonation : Pos 1, 1 Bit</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x52c DisallowUsermodeSiloThreadImpersonation : Pos 2, 1 Bit</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x5f0 SiloHardReferenceCount : Int8B</span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">_ESERVERSILO_GLOBALS</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">结构保存</span><span style="font-family:Calibri;">silo</span><span style="font-family:宋体;">的状态信息。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="http"><code><span class="code-snippet_outer"><span class="code-snippet__attribute">1</span>: kd&gt; dt nt!_ESERVERSILO_GLOBALS</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x000 ObSiloState      : _OBP_SILODRIVERSTATE</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x2e0 SeSiloState      : _SEP_SILOSTATE</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x310 SeRmSiloState    : _SEP_RM_LSA_CONNECTION_STATE</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x360 EtwSiloState     : Ptr64 _ETW_SILODRIVERSTATE</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x368 MiSessionLeaderProcess : Ptr64 _EPROCESS</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x370 ExpDefaultErrorPortProcess : Ptr64 _EPROCESS</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x378 ExpDefaultErrorPort : Ptr64 Void</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x380 HardErrorState   : Uint4B</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x388 ExpLicenseState  : Ptr64 _EXP_LICENSE_STATE</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x390 WnfSiloState     : _WNF_SILODRIVERSTATE</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x3c8 DbgkSiloState    : _DBGK_SILOSTATE</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x3e8 PsProtectedCurrentDirectory : _UNICODE_STRING</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x3f8 PsProtectedEnvironment : _UNICODE_STRING</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x408 ApiSetSection    : Ptr64 Void</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x410 ApiSetSchema     : Ptr64 Void</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x418 OneCoreForwardersEnabled : UChar</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x419 TzVirtualizationSupported : UChar</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x420 ImgFileExecOptions : Ptr64 Void</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x428 ExTimeZoneState  : Ptr64 _EX_TIMEZONE_STATE</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x430 NtSystemRoot     : _UNICODE_STRING</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x440 SiloRootDirectoryName : _UNICODE_STRING</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x450 Storage          : Ptr64 _PSP_STORAGE</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x458 State            : _SERVERSILO_STATE</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x45c ExitStatus       : Int4B</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x460 DeleteEvent      : Ptr64 _KEVENT</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x468 UserSharedData   : Ptr64 _SILO_USER_SHARED_DATA</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x470 UserSharedSection : Ptr64 Void</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x478 TerminateWorkItem : _WORK_QUEUE_ITEM</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x498 IsDownlevelContainer : UChar</span></span></code></pre></section><h2><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">2.3</span><span style="font-family:黑体;">内核接口实现</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><h3><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">2.3.1 PspCreateSilo</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h3><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  建立</span><span style="font-family:Calibri;">silo</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">storage</span><span style="font-family:宋体;">结构。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001405D3FAC</span> <span class="code-snippet__selector-tag">PspCreateSilo</span> <span class="code-snippet__selector-tag">proc</span> <span class="code-snippet__selector-tag">near</span>               ; <span class="code-snippet__selector-tag">CODE</span> <span class="code-snippet__selector-tag">XREF</span>: <span class="code-snippet__selector-tag">NtSetInformationJobObject</span>+1<span class="code-snippet__selector-tag">A1C</span>↓<span class="code-snippet__selector-tag">p</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001405D3FAC</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001405D3FD2</span> <span class="code-snippet__selector-tag">call</span>    <span class="code-snippet__selector-tag">PsIsCurrentThreadInServerSilo</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001405D3FD7</span> <span class="code-snippet__selector-tag">test</span>    <span class="code-snippet__selector-tag">al</span>, <span class="code-snippet__selector-tag">al</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001405D3FD9</span> <span class="code-snippet__selector-tag">jz</span>      <span class="code-snippet__selector-tag">short</span> <span class="code-snippet__selector-tag">loc_1405D3FE5</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001405D3FDB</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">eax</span>, 0<span class="code-snippet__selector-tag">C0000061h</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001405D3FE0</span> <span class="code-snippet__selector-tag">jmp</span>     <span class="code-snippet__selector-tag">loc_1405D4088</span></span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  如果当前进程已经有一个</span>silo<span style="font-family:宋体;">，则直接返回。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001405D3FE5</span> <span class="code-snippet__selector-tag">cmp</span>     <span class="code-snippet__selector-attr">[rbx+518h]</span>, <span class="code-snippet__selector-tag">rdi</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001405D3FEC</span> <span class="code-snippet__selector-tag">jnz</span>     <span class="code-snippet__selector-tag">short</span> <span class="code-snippet__selector-tag">loc_1405D4005</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001405D3FEE</span> <span class="code-snippet__selector-tag">lea</span>     <span class="code-snippet__selector-tag">rcx</span>, <span class="code-snippet__selector-attr">[rsp+28h+arg_8]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001405D3FF3</span> <span class="code-snippet__selector-tag">call</span>    <span class="code-snippet__selector-tag">PspAllocStorage</span></span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  判断</span>ejob-&gt;Storage<span style="font-family:宋体;">如果为空则调用</span><span style="font-family:Calibri;">PspAllocStorage</span><span style="font-family:宋体;">分配一个</span><span style="font-family:Calibri;">silo context</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001405D4013</span> <span class="code-snippet__selector-tag">call</span>    <span class="code-snippet__selector-tag">PspJobHasChildren</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001405D4018</span> <span class="code-snippet__selector-tag">test</span>    <span class="code-snippet__selector-tag">al</span>, <span class="code-snippet__selector-tag">al</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001405D401A</span> <span class="code-snippet__selector-tag">jz</span>      <span class="code-snippet__selector-tag">short</span> <span class="code-snippet__selector-tag">loc_1405D4023</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001405D401C</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">esi</span>, 0<span class="code-snippet__selector-tag">C000050Fh</span></span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  如果</span>job<span style="font-family:宋体;">存在子进程，设置</span><span style="font-family:Calibri;">esi</span><span style="font-family:宋体;">为</span><span style="font-family:Calibri;">0C000050Fh</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001405D4023</span> <span class="code-snippet__selector-tag">loc_1405D4023</span>: ; <span class="code-snippet__selector-tag">CODE</span> <span class="code-snippet__selector-tag">XREF</span>: <span class="code-snippet__selector-tag">PspCreateSilo</span>+6<span class="code-snippet__selector-tag">E</span>↑<span class="code-snippet__selector-tag">j</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001405D4023</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">edx</span>, 40000000<span class="code-snippet__selector-tag">h</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001405D4028</span> <span class="code-snippet__selector-tag">test</span>    <span class="code-snippet__selector-attr">[rbx+528h]</span>, <span class="code-snippet__selector-tag">edx</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001405D402E</span> <span class="code-snippet__selector-tag">jz</span>      <span class="code-snippet__selector-tag">short</span> <span class="code-snippet__selector-tag">loc_1405D4037</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001405D4030</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">esi</span>, 0<span class="code-snippet__selector-tag">C0000508h</span></span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  如果</span>ejob-&gt;Silo == 1<span style="font-family:宋体;">，设置</span><span style="font-family:Calibri;">esi</span><span style="font-family:宋体;">为</span><span style="font-family:Calibri;">0C0000508h</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001405D404A</span> <span class="code-snippet__selector-tag">loc_1405D404A</span>: ; <span class="code-snippet__selector-tag">CODE</span> <span class="code-snippet__selector-tag">XREF</span>: <span class="code-snippet__selector-tag">PspCreateSilo</span>+95↑<span class="code-snippet__selector-tag">j</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001405D404A</span> <span class="code-snippet__selector-tag">xor</span>     <span class="code-snippet__selector-tag">eax</span>, <span class="code-snippet__selector-tag">eax</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001405D404C</span> <span class="code-snippet__selector-tag">lock</span> <span class="code-snippet__selector-tag">cmpxchg</span> <span class="code-snippet__selector-attr">[rbx+518h]</span>, <span class="code-snippet__selector-tag">rdi</span></span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  将当前</span>ejob-&gt;Storage<span style="font-family:宋体;">值与</span><span style="font-family:Calibri;">PspAllocStorage</span><span style="font-family:宋体;">分配的地址互换。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  接着看下</span>PspAllocStorage<span style="font-family:宋体;">的实现：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014064EF40</span> ; __<span class="code-snippet__selector-tag">int64</span> __<span class="code-snippet__selector-tag">fastcall</span> <span class="code-snippet__selector-tag">PspAllocStorage</span>(_<span class="code-snippet__selector-tag">QWORD</span> *)</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014064EF40</span> <span class="code-snippet__selector-tag">PspAllocStorage</span> <span class="code-snippet__selector-tag">proc</span> <span class="code-snippet__selector-tag">near</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014064EF46</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">edx</span>, 240<span class="code-snippet__selector-tag">h</span>       ; <span class="code-snippet__selector-tag">NumberOfBytes</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014064EF4B</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">rbx</span>, <span class="code-snippet__selector-tag">rcx</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014064EF4E</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">r8d</span>, 74537350<span class="code-snippet__selector-tag">h</span>  ; <span class="code-snippet__selector-tag">Tag</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014064EF54</span> <span class="code-snippet__selector-tag">lea</span>     <span class="code-snippet__selector-tag">ecx</span>, <span class="code-snippet__selector-attr">[rdx-3Ch]</span>  ; <span class="code-snippet__selector-tag">PoolType</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014064EF57</span> <span class="code-snippet__selector-tag">call</span>    <span class="code-snippet__selector-tag">ExAllocatePoolWithTag</span></span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  微软符号表中并没有给出</span>_PSP_STORAGE<span style="font-family:宋体;">结构体的定义。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="javascript"><code><span class="code-snippet_outer">lkd&gt; dt nt!_PSP_STORAGE</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__built_in">Symbol</span> nt!_PSP_STORAGE not found.</span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  但是根据传递给</span>ExAllocatePoolWithTag<span style="font-family:宋体;">函数的第二个参数为</span><span style="font-family:Calibri;">240h</span><span style="font-family:宋体;">，所以可以断定</span><span style="font-family:Calibri;">_PSP_STORAGE</span><span style="font-family:宋体;">结构体大小为</span><span style="font-family:Calibri;">240h</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014064EF67</span> <span class="code-snippet__selector-tag">lea</span>     <span class="code-snippet__selector-tag">ecx</span>, <span class="code-snippet__selector-attr">[r8+20h]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014064EF6B</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014064EF6B</span> <span class="code-snippet__selector-tag">loc_14064EF6B</span>: ; <span class="code-snippet__selector-tag">CODE</span> <span class="code-snippet__selector-tag">XREF</span>: <span class="code-snippet__selector-tag">PspAllocStorage</span>+3<span class="code-snippet__selector-tag">A</span>↓<span class="code-snippet__selector-tag">j</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014064EF6B</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-attr">[rax]</span>, <span class="code-snippet__selector-tag">r8</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014064EF6E</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-attr">[rax+8]</span>, <span class="code-snippet__selector-tag">r8</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014064EF72</span> <span class="code-snippet__selector-tag">lea</span>     <span class="code-snippet__selector-tag">rax</span>, <span class="code-snippet__selector-attr">[rax+10h]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014064EF76</span> <span class="code-snippet__selector-tag">sub</span>     <span class="code-snippet__selector-tag">rcx</span>, 1</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014064EF7A</span> <span class="code-snippet__selector-tag">jnz</span>     <span class="code-snippet__selector-tag">short</span> <span class="code-snippet__selector-tag">loc_14064EF6B</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014064EF7C</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-attr">[rdx+200h]</span>, <span class="code-snippet__selector-tag">r8</span></span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  ecx<span style="font-family:宋体;">设置为</span><span style="font-family:Calibri;">32</span><span style="font-family:宋体;">，将</span><span style="font-family:Calibri;">storage</span><span style="font-family:宋体;">地址依次设为</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">，可以试着组建一下</span><span style="font-family:Calibri;">_PSP_STORAGE</span><span style="font-family:宋体;">结构体：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> _<span class="code-snippet__title">PSP_STORAGE</span> {</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">slot_type slots[<span class="code-snippet__number">32</span>];</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">...</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">slot_type</span> {</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">void</span> *ptr1;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">void</span> *ptr2;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><h3><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">2.3.2 PspSetJobSiloThreadImpersonationPolicy</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h3><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  启用或关闭</span><span style="font-family:Calibri;">silo</span><span style="font-family:宋体;">，它有两个参数第一个为</span><span style="font-family:Calibri;">ejob</span><span style="font-family:宋体;">结构，第</span><span style="font-family:Calibri;">2</span><span style="font-family:宋体;">个为</span><span style="font-family:Calibri;">silo</span><span style="font-family:宋体;">的状态值。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">AGE</span><span class="code-snippet__selector-pseudo">:0000000140909864</span> <span class="code-snippet__selector-tag">PspSetJobSiloThreadImpersonationPolicy</span> <span class="code-snippet__selector-tag">proc</span> <span class="code-snippet__selector-tag">near</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140909864</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">eax</span>, 2</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140909869</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">r9</span>, <span class="code-snippet__selector-tag">rcx</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014090986C</span> <span class="code-snippet__selector-tag">cmp</span>     <span class="code-snippet__selector-tag">edx</span>, <span class="code-snippet__selector-tag">eax</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014090986E</span> <span class="code-snippet__selector-tag">lea</span>     <span class="code-snippet__selector-tag">r8d</span>, <span class="code-snippet__selector-attr">[rax+2]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140909872</span> <span class="code-snippet__selector-tag">cmovnz</span>  <span class="code-snippet__selector-tag">r8d</span>, <span class="code-snippet__selector-tag">eax</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140909876</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">eax</span>, <span class="code-snippet__selector-attr">[rcx+52Ch]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014090987C</span> <span class="code-snippet__selector-tag">test</span>    <span class="code-snippet__selector-tag">edx</span>, <span class="code-snippet__selector-tag">eax</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014090987E</span> <span class="code-snippet__selector-tag">jz</span>      <span class="code-snippet__selector-tag">short</span> <span class="code-snippet__selector-tag">loc_140909895</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140909880</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140909880</span> <span class="code-snippet__selector-tag">loc_140909880</span>: <span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140909880</span>                 <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">al</span>, 1</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140909882</span> <span class="code-snippet__selector-tag">retn</span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;"> 如果第二个参数不为</span><span style="font-family:Calibri;">2</span><span style="font-family:宋体;">，强行设为</span><span style="font-family:Calibri;">2</span><span style="font-family:宋体;">，如果</span><span style="font-family:Calibri;">ejob-&gt;EnableUsermodeSiloThreadImpersonation</span><span style="font-family:宋体;">已经置位则返回。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140909884</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140909884</span> <span class="code-snippet__selector-tag">loc_140909884</span>:</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140909884</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">ecx</span>, <span class="code-snippet__selector-tag">eax</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140909886</span> <span class="code-snippet__selector-tag">or</span>      <span class="code-snippet__selector-tag">ecx</span>, <span class="code-snippet__selector-tag">edx</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140909888</span> <span class="code-snippet__selector-tag">lock</span> <span class="code-snippet__selector-tag">cmpxchg</span> <span class="code-snippet__selector-attr">[r9+52Ch]</span>, <span class="code-snippet__selector-tag">ecx</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140909891</span> <span class="code-snippet__selector-tag">cmp</span>     <span class="code-snippet__selector-tag">eax</span>, <span class="code-snippet__selector-tag">ecx</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140909893</span> <span class="code-snippet__selector-tag">jz</span>      <span class="code-snippet__selector-tag">short</span> <span class="code-snippet__selector-tag">loc_140909880</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140909895</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140909895</span> <span class="code-snippet__selector-tag">loc_140909895</span>: ; <span class="code-snippet__selector-tag">CODE</span> <span class="code-snippet__selector-tag">XREF</span>: <span class="code-snippet__selector-tag">PspSetJobSiloThreadImpersonationPolicy</span>+1<span class="code-snippet__selector-tag">A</span>↑<span class="code-snippet__selector-tag">j</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140909895</span> <span class="code-snippet__selector-tag">test</span>    <span class="code-snippet__selector-tag">eax</span>, <span class="code-snippet__selector-tag">r8d</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140909898</span> <span class="code-snippet__selector-tag">jz</span>      <span class="code-snippet__selector-tag">short</span> <span class="code-snippet__selector-tag">loc_140909884</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014090989A</span> <span class="code-snippet__selector-tag">xor</span>     <span class="code-snippet__selector-tag">al</span>, <span class="code-snippet__selector-tag">al</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014090989C</span> <span class="code-snippet__selector-tag">retn</span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  设置</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">ejob-&gt;EnableUsermodeSiloThreadImpersonation |= 2</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">。</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h3><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">2.3.3 ObInitServerSilo</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h3><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="makefile"><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407C0E70 ; NTSTATUS __fastcall ObInitServerSilo(__int64)</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407C0E70 ObInitServerSilo proc near</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407C0E9D and     qword ptr [rax+78h], 0 ; _ESERVERSILO_GLOBALS-&gt;ObSiloState-&gt;DeviceMapLock = 0</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407C0EA2 lea     rdx, [rax+80h]  ; _ESERVERSILO_GLOBALS-&gt;ObSiloState-&gt;PrivateNamespaceLookupTable</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407C0EA9 and     qword ptr [rdx+250h], 0 ; _ESERVERSILO_GLOBALS-&gt;ObSiloState-&gt;PrivateNamespaceLookupTable-&gt;Lock = 0</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407C0EB1 mov     eax, 25h ; &#39;%&#39;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407C0EB6</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407C0EB6 loc_1407C0EB6: ; CODE XREF: ObInitServerSilo+55↓j</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407C0EB6 mov     [rdx+8], rdx</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407C0EBA mov     [rdx], rdx</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407C0EBD add     rdx, 10h</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407C0EC1 sub     rax, 1</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407C0EC5 jnz     short loc_1407C0EB6</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407C0EC7 call    PsIsHostSilo</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407C0ECC test    al, al</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407C0ECE jz      loc_14085E746</span></span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  初始化</span>ejob-&gt;ObSiloState<span style="font-family:宋体;">结构，</span><span style="font-family:Calibri;">ObSiloState-&gt;PrivateNamespaceLookupTable</span><span style="font-family:宋体;">是一个哈希表，每个项是一个双向链表节点，</span><span style="font-family:Calibri;">blink,flink</span><span style="font-family:宋体;">都指向自己。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014085E753</span> <span class="code-snippet__selector-tag">call</span>    <span class="code-snippet__selector-tag">PsGetPermanentSiloContext</span></span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">    ejob-&gt;0x518<span style="font-family:宋体;">地址保存</span><span style="font-family:Calibri;">silo context</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h3><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">2.3.4 </span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;">PspInitializeProtectedProcessParameters</span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h3><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  设置进程的</span>enviorment<span style="font-family:宋体;">内容</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="makefile"><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC430 ; __int64 __fastcall PspInitializeProtectedProcessParameters(__int64)</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC430 PspInitializeProtectedProcessParameters proc near</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC44F movdqu  xmmword ptr [rcx+3E8h], xmm0 ; _ESERVERSILO_GLOBALS-&gt;PsProtectedCurrentDirectory = _ESERVERSILO_GLOBALS-&gt;NtSystemRoot</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC457 movzx   eax, word ptr [rcx+430h]</span></span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  首先设置</span>_ESERVERSILO_GLOBALS-&gt;PsProtectedCurrentDirectory</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="makefile"><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC457 movzx   eax, word ptr [rcx+430h]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC45E movups  xmm1, xmmword ptr [rcx+430h]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC465 add     ax, 2Ah ; &#39;*&#39;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC469 add     ax, ax</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC46C mov     [rcx+3F8h], ax  ; PsProtectedEnvironment = (NtSystemRoot + 0x2a) * 2</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC473 add     ax, 2</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC477 movzx   edx, ax         ; NumberOfBytes</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC47A mov     [rcx+3FAh], dx</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC481 mov     ecx, 1          ; PoolType</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC486 movdqu  [rsp+38h+var_18], xmm1</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC48C call    ExAllocatePoolWithTag ; (1, NumberOfBytes)</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC491 xor     esi, esi</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC493 mov     [rdi+400h], rax ; PsProtectedEnvironment + 8</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC49A mov     rbx, rax</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC49D test    rax, rax</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC4A0 jz      loc_14085D110</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC4A6 mov     rax, cs:off_140983D28 ; &#34;Path=&#34;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC4AD movsd   xmm0, qword ptr [rax]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC4B1 movsd   qword ptr [rbx], xmm0</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC4B5 movzx   eax, word ptr [rax+8]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC4B9 mov     [rbx+8], ax</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC4BD add     rbx, 0Ah</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC4C1 movzx   r8d, word ptr [rdi+430h] ; Size</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC4C9 mov     rcx, rbx        ; void *</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC4CC mov     rdx, [rdi+438h] ; Src</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC4D3 call    memmove         ; Path=NtSystemRoot+8</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC4D8 mov     rax, cs:off_140983D18 ; &#34;\\System32&#34;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC4DF movzx   edx, word ptr [rdi+430h] ; NtSystemRoot-&gt;Length</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC4E6 movups  xmm0, xmmword ptr [rax]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC4E9 movups  xmmword ptr [rdx+rbx], xmm0</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC4ED movzx   eax, word ptr [rax+10h]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC4F1 mov     [rdx+rbx+10h], ax</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC4F6 mov     [rdx+rbx+12h], si</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC4FB mov     rax, cs:off_140983D38 ; &#34;SystemDrive=&#34;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC502 movups  xmm0, xmmword ptr [rax]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC505 movups  xmmword ptr [rdx+rbx+14h], xmm0</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC50A movsd   xmm1, qword ptr [rax+10h]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC50F mov     rax, qword ptr [rsp+38h+var_18+8] ; NtSystemRoot-&gt;Buffer</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC514 movsd   qword ptr [rdx+rbx+24h], xmm1</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC51A mov     ecx, [rax]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC51C mov     [rdx+rbx+2Ch], ecx</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC520 mov     [rdx+rbx+30h], si</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC525 mov     rcx, cs:off_140983D48 ; &#34;SystemRoot=&#34;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC52C movups  xmm0, xmmword ptr [rcx]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC52F movups  xmmword ptr [rdx+rbx+32h], xmm0</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC534 mov     eax, [rcx+10h]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC537 mov     [rdx+rbx+42h], eax</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC53B movzx   eax, word ptr [rcx+14h]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC53F mov     [rdx+rbx+46h], ax</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC544 add     rbx, rdx</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC547 movzx   r8d, word ptr [rdi+430h] ; Size</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC54F mov     rdx, [rdi+438h] ; Src</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC556 lea     rcx, [rbx+48h]  ; void *</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:00000001407BC55A call    memmove         ; NtSystemRoot</span></span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  构造</span>PsProtectedEnvironment<span style="font-family:宋体;">内容：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">+-------------------------------------------------------------------------------------------------------------------+</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">| Path= | NtSystemRoot-&gt;Buffer| \\System32 | SystemDrive= | NtSystemRoot-&gt;Buffer[0]|SystemRoot=|NtSystemRoot-&gt;Buffer |</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">+-------------------------------------------------------------------------------------------------------------------+</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  一共</span>3<span style="font-family:宋体;">个环境变量： </span><span style="font-family:Calibri;">Path</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">SystemDrive</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">SystemRoot</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h3><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">2.3.5 PspSiloInitializeSystemRootSymlink</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h3><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140906AF0</span> ; <span class="code-snippet__selector-tag">NTSTATUS</span> __<span class="code-snippet__selector-tag">fastcall</span> <span class="code-snippet__selector-tag">PspSiloInitializeSystemRootSymlink</span>(_<span class="code-snippet__selector-tag">LIST_ENTRY</span> *)</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140906AF0</span> <span class="code-snippet__selector-tag">PspSiloInitializeSystemRootSymlink</span> <span class="code-snippet__selector-tag">proc</span> <span class="code-snippet__selector-tag">nea</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140906B8F</span> <span class="code-snippet__selector-tag">call</span>    <span class="code-snippet__selector-tag">RtlAppendUnicodeStringToString</span> ; \\<span class="code-snippet__selector-tag">GLOBAL</span>??\\ + _<span class="code-snippet__selector-tag">ESERVERSILO_GLOBALS-</span>&gt;<span class="code-snippet__selector-tag">NtSystemRoot</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140906B94</span> <span class="code-snippet__selector-tag">lea</span>     <span class="code-snippet__selector-tag">rax</span>, <span class="code-snippet__selector-tag">PspSystemRootSymlinkName</span> ; \\<span class="code-snippet__selector-tag">SystemRoot</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140906BC1</span> <span class="code-snippet__selector-tag">lea</span>     <span class="code-snippet__selector-tag">r9</span>, <span class="code-snippet__selector-attr">[rbp+DestinationString]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140906BC5</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">edx</span>, 0<span class="code-snippet__selector-tag">F0001h</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140906BCA</span> <span class="code-snippet__selector-tag">lea</span>     <span class="code-snippet__selector-tag">r8</span>, <span class="code-snippet__selector-attr">[rbp+var_30]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140906BCE</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">rbx</span>, <span class="code-snippet__selector-tag">rax</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140906BD1</span> <span class="code-snippet__selector-tag">lea</span>     <span class="code-snippet__selector-tag">rcx</span>, <span class="code-snippet__selector-attr">[rbp+Handle]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140906BD5</span> <span class="code-snippet__selector-tag">call</span>    <span class="code-snippet__selector-tag">ZwCreateSymbolicLinkObject</span></span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  调用未公开接口</span>ZwCreateSymbolicLinkObject<span style="font-family:宋体;">建立</span><span style="font-family:Calibri;">\\SystemRoot</span><span style="font-family:宋体;">到</span><span style="font-family:Calibri;">\\GLOBAL??\\ + _ESERVERSILO_GLOBALS-&gt;NtSystemRoot</span><span style="font-family:宋体;">的软链接？</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h3><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">2.3.6  PspSiloInitializeUserSharedData</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h3><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="makefile"><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:0000000140906C1C ; __int64 __fastcall PspSiloInitializeUserSharedData(_LIST_ENTRY *)</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:0000000140906C1C PspSiloInitializeUserSharedData proc near</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:0000000140906CB3 mov     [rax+468h], rcx ; _ESERVERSILO_GLOBALS-&gt;serSharedData = MappedBase</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:0000000140906CBA mov     rcx, rsi</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">PAGE:0000000140906CBD mov     [rax+470h], rbx ; _ESERVERSILO_GLOBALS-&gt;UserSharedSection = Section</span></span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  设置</span>silo<span style="font-family:宋体;">的</span><span style="font-family:Calibri;">serSharedData</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">UserSharedSection</span><span style="font-family:宋体;">字段。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h3><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">2.3.7 PspSiloInitializeLicenseData</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h3><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">PspSiloInitializeLicenseData<span style="font-family:宋体;">函数初始化</span><span style="font-family:Calibri;">silo</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">License Data</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:00000001405B03A8</span> ; __<span class="code-snippet__selector-tag">int64</span> __<span class="code-snippet__selector-tag">fastcall</span> <span class="code-snippet__selector-tag">PspSiloInitializeLicenseData</span>(_<span class="code-snippet__selector-tag">LIST_ENTRY</span> *)</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:00000001405B03A8</span> <span class="code-snippet__selector-tag">PspSiloInitializeLicenseData</span> <span class="code-snippet__selector-tag">proc</span> <span class="code-snippet__selector-tag">near</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:00000001405B0406</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">edx</span>, 0<span class="code-snippet__selector-tag">B7C0h</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:00000001405B040B</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">ecx</span>, 100<span class="code-snippet__selector-tag">h</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:00000001405B0410</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">r8d</span>, 69534<span class="code-snippet__selector-tag">C53h</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:00000001405B0416</span> <span class="code-snippet__selector-tag">call</span>    <span class="code-snippet__selector-tag">ExAllocatePool2</span> ; <span class="code-snippet__selector-tag">struct</span> _<span class="code-snippet__selector-tag">EXP_LICENSE_STATE</span></span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  分配</span>struct _EXP_LICENSE_STATE<span style="font-family:宋体;">结构体，微软符号表中未提供它的数据结构。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:00000001405B049F</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-attr">[rbx+388h]</span>, <span class="code-snippet__selector-tag">rsi</span> ; <span class="code-snippet__selector-tag">ejob-</span>&gt;<span class="code-snippet__selector-tag">ExpLicenseState</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:00000001405B04A6</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-attr">[rbp+57h+var_68]</span>, 100<span class="code-snippet__selector-tag">h</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:00000001405B04AD</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-attr">[rbp+57h+var_50]</span>, 3000003<span class="code-snippet__selector-tag">h</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:00000001405B04B4</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-attr">[rbp+57h+var_40]</span>, 14000<span class="code-snippet__selector-tag">h</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:00000001405B04BB</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-attr">[rbp+57h+var_58]</span>, <span class="code-snippet__selector-tag">rsi</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:00000001405B04BF</span> <span class="code-snippet__selector-tag">call</span>    <span class="code-snippet__selector-tag">ExpInitLicensing</span></span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">    ExpInitLicensing <span style="font-family:宋体;">做简单初始化，如果是全局</span><span style="font-family:Calibri;">silo</span><span style="font-family:宋体;">变量</span><span style="font-family:Calibri;">PspHostSiloGlobals</span><span style="font-family:宋体;">，使用</span><span style="font-family:Calibri;">ExpHostBootLicensingData</span><span style="font-family:宋体;">作为默认的</span><span style="font-family:Calibri;">license data</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:00000001405B04D7</span> <span class="code-snippet__selector-tag">lea</span>     <span class="code-snippet__selector-tag">rdx</span>, <span class="code-snippet__selector-tag">aProductoptions_0</span> ; &#34;<span class="code-snippet__selector-tag">ProductOptions</span>&#34;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:00000001405B04DE</span> <span class="code-snippet__selector-tag">xor</span>     <span class="code-snippet__selector-tag">r9d</span>, <span class="code-snippet__selector-tag">r9d</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:00000001405B04E1</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">rbx</span>, <span class="code-snippet__selector-attr">[rcx+608h]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:00000001405B04E8</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-attr">[rcx+608h]</span>, <span class="code-snippet__selector-tag">rdi</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:00000001405B04EF</span> <span class="code-snippet__selector-tag">lea</span>     <span class="code-snippet__selector-tag">ecx</span>, <span class="code-snippet__selector-attr">[r9+2]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:00000001405B04F3</span> <span class="code-snippet__selector-tag">call</span>    <span class="code-snippet__selector-tag">RtlQueryRegistryValuesEx</span> ; (<span class="code-snippet__selector-tag">gs</span><span class="code-snippet__selector-pseudo">:188h</span>, &#34;<span class="code-snippet__selector-tag">ProductOptions</span>&#34;, <span class="code-snippet__selector-tag">ExpQueryRegistryRoutine</span>, 0)</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:00000001405B04F8</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">edi</span>, <span class="code-snippet__selector-tag">eax</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:00000001405B04FA</span> <span class="code-snippet__selector-tag">call</span>    <span class="code-snippet__selector-tag">ExInitLicenseData</span></span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  查询注册表</span>ProductOptions<span style="font-family:宋体;">键值，</span><span style="font-family:Calibri;">ExpQueryRegistryRoutine</span><span style="font-family:宋体;">为回调函数。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">      ExInitLicenseData<span style="font-family:宋体;">初始化</span><span style="font-family:Calibri;">license</span><span style="font-family:宋体;">的关键函数，过于复杂，未跟踪。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h2><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">2.4 Namespace</span><span style="font-family:黑体;">隔离</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h2><h3><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">2.4.1 </span><span style="font-family:宋体;">注册表隔离</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h3><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  每个</span><span style="font-family:Calibri;">silo</span><span style="font-family:宋体;">进程都有独立的注册表</span><span style="font-family:Calibri;">namespace</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014068B2E0</span> <span class="code-snippet__selector-tag">CmpParseKey</span> <span class="code-snippet__selector-tag">proc</span> <span class="code-snippet__selector-tag">near</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014068B689</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">rcx</span>, <span class="code-snippet__selector-attr">[r13+8]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014068B68D</span> <span class="code-snippet__selector-tag">call</span>    <span class="code-snippet__selector-tag">CmpGetRegistryNamespaceRootForSilo</span></span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">   CmpGetRegistryNamespaceRootForSilo<span style="font-family:宋体;">调用</span><span style="font-family:Calibri;">PsGetPermanentSiloContext</span><span style="font-family:宋体;">获取</span><span style="font-family:Calibri;">ejob-&gt;Storage</span><span style="font-family:宋体;">的地址。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140687B1F</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">rax</span>, <span class="code-snippet__selector-attr">[rax+20h]</span></span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">	</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">    ejob-&gt;Storage.slots[32]<span style="font-family:宋体;">为</span><span style="font-family:Calibri;">vreg namespace</span><span style="font-family:宋体;">的地址。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h3><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">2.4.2 </span><span style="font-family:宋体;">进程隔离</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h3><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001406746A0</span> ; <span class="code-snippet__selector-tag">NTSTATUS</span> __<span class="code-snippet__selector-tag">stdcall</span> <span class="code-snippet__selector-tag">PsLookupThreadByThreadId</span>(<span class="code-snippet__selector-tag">HANDLE</span> <span class="code-snippet__selector-tag">ThreadId</span>, <span class="code-snippet__selector-tag">PETHREAD</span> *<span class="code-snippet__selector-tag">Thread</span>)</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001406746A0</span> <span class="code-snippet__selector-tag">public</span> <span class="code-snippet__selector-tag">PsLookupThreadByThreadId</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001406746A0</span> <span class="code-snippet__selector-tag">PsLookupThreadByThreadId</span> <span class="code-snippet__selector-tag">proc</span> <span class="code-snippet__selector-tag">near</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001406746B5</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">rsi</span>, <span class="code-snippet__selector-tag">gs</span><span class="code-snippet__selector-pseudo">:188h</span>    ; <span class="code-snippet__selector-tag">CurrentThread</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001406746BE</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">r14</span>, <span class="code-snippet__selector-tag">rdx</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001406746C1</span> <span class="code-snippet__selector-tag">dec</span>     <span class="code-snippet__selector-tag">word</span> <span class="code-snippet__selector-tag">ptr</span> <span class="code-snippet__selector-attr">[rsi+1E6h]</span> ; <span class="code-snippet__selector-tag">--CurrentThread-</span>&gt;<span class="code-snippet__selector-tag">SpecialApcDisable</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001406746C8</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">dl</span>, 6</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001406746CA</span> <span class="code-snippet__selector-tag">call</span>    <span class="code-snippet__selector-tag">PspReferenceCidTableEntry</span> ; (<span class="code-snippet__selector-tag">ThreadId</span>, 6)</span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    PspReferenceCidTableEntry</span><span style="font-family:宋体;">函数根据</span><span style="font-family:Calibri;">ThreadId</span><span style="font-family:宋体;">返回对应的</span><span style="font-family:Calibri;">ethread</span><span style="font-family:宋体;">结构体。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:00000001406746D7</span> <span class="code-snippet__selector-tag">call</span>    <span class="code-snippet__selector-tag">PsGetCurrentServerSilo</span></span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">	</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  得到当前进程的</span><span style="font-family:Calibri;">ejob</span><span style="font-family:宋体;">结构体。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014067470D</span> <span class="code-snippet__selector-tag">loc_14067470D</span>: ; <span class="code-snippet__selector-tag">CODE</span> <span class="code-snippet__selector-tag">XREF</span>: <span class="code-snippet__selector-tag">PsLookupThreadByThreadId</span>+48↑<span class="code-snippet__selector-tag">j</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014067470D</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">rcx</span>, <span class="code-snippet__selector-attr">[rbx+220h]</span> ; (<span class="code-snippet__selector-tag">kproces</span> *)<span class="code-snippet__selector-tag">thread-</span>&gt;<span class="code-snippet__selector-tag">tcb-</span>&gt;<span class="code-snippet__selector-tag">process</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140674714</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">rdx</span>, <span class="code-snippet__selector-tag">rdi</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140674717</span> <span class="code-snippet__selector-tag">call</span>    <span class="code-snippet__selector-tag">PsIsProcessInSilo</span> ; (<span class="code-snippet__selector-tag">kprocess</span>, <span class="code-snippet__selector-tag">ejob</span>)</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014067471C</span> <span class="code-snippet__selector-tag">test</span>    <span class="code-snippet__selector-tag">al</span>, <span class="code-snippet__selector-tag">al</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014067471E</span> <span class="code-snippet__selector-tag">jnz</span>     <span class="code-snippet__selector-tag">short</span> <span class="code-snippet__selector-tag">loc_14067472A</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140674720</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140674720</span> <span class="code-snippet__selector-tag">loc_140674720</span>: ; <span class="code-snippet__selector-tag">CODE</span> <span class="code-snippet__selector-tag">XREF</span>: <span class="code-snippet__selector-tag">PsLookupThreadByThreadId</span>+6<span class="code-snippet__selector-tag">B</span>↑<span class="code-snippet__selector-tag">j</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140674720</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">rcx</span>, <span class="code-snippet__selector-tag">rbx</span>        ; <span class="code-snippet__selector-tag">DmaAdapter</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140674723</span> <span class="code-snippet__selector-tag">call</span>    <span class="code-snippet__selector-tag">HalPutDmaAdapter</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140674728</span> <span class="code-snippet__selector-tag">xor</span>     <span class="code-snippet__selector-tag">ebx</span>, <span class="code-snippet__selector-tag">ebx</span></span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    PsIsProcessInSilo</span><span style="font-family:宋体;">函数有两个参数，第一个参数为要得到</span><span style="font-family:Calibri;">handle</span><span style="font-family:宋体;">的目标进程</span><span style="font-family:Calibri;">kprocess</span><span style="font-family:宋体;">结构体， 第二个参数为当前进程的</span><span style="font-family:Calibri;">ejob</span><span style="font-family:宋体;">结构体，</span></span><span style="font-family: 宋体;font-size: 10.5pt;letter-spacing: 0.034em;">如果返回值为</span><span style="font-size: 10.5pt;letter-spacing: 0.034em;font-family: Calibri;">0</span><span style="font-family: 宋体;font-size: 10.5pt;letter-spacing: 0.034em;">就不能获取目标进程的</span><span style="font-size: 10.5pt;letter-spacing: 0.034em;font-family: Calibri;">Handle</span><span style="font-family: 宋体;font-size: 10.5pt;letter-spacing: 0.034em;">，为</span><span style="font-size: 10.5pt;letter-spacing: 0.034em;font-family: Calibri;">1</span><span style="font-family: 宋体;font-size: 10.5pt;letter-spacing: 0.034em;">则可以。</span></p><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">	</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">下面仔细分析下这个函数：</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="makefile"><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:0000000140273948 PsIsProcessInSilo proc near ; CODE XREF: PsIsThreadInSilo+29↑p</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:0000000140273948 ; PsLookupThreadByThreadId+77↓p ...</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:0000000140273948 sub     rsp, 28h</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:000000014027394C test    rdx, rdx</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:000000014027394F jnz     short loc_140273959</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:0000000140273951</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:0000000140273951 loc_140273951: ; CODE XREF: PsIsProcessInSilo+18↓j</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:0000000140273951 ; PsIsProcessInSilo+21↓j</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:0000000140273951 mov     al, 1           ; ejob == NULL</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:0000000140273953</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:0000000140273953 loc_140273953: ; CODE XREF: PsIsProcessInSilo+3C↓j</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:0000000140273953 add     rsp, 28h</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:0000000140273957 retn</span></span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  如果第二个参数</span><span style="font-family:Calibri;">ejob</span><span style="font-family:宋体;">为空则返回</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="makefile"><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:0000000140273959</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:0000000140273959 loc_140273959: ; CODE XREF: PsIsProcessInSilo+7↑j</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:0000000140273959 cmp     rcx, cs:PsInitialSystemProcess</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:0000000140273960 jz      short loc_140273951 ; ejob == NULL</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:0000000140273962 cmp     rcx, cs:PsIdleProcess</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:0000000140273969 jz      short loc_140273951 ; ejob == NULL</span></span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  如果第一个参数</span><span style="font-family:Calibri;">kprocess</span><span style="font-family:宋体;">为</span><span style="font-family:Calibri;">PsInitialSystemProcess</span><span style="font-family:宋体;">或</span><span style="font-family:Calibri;">PsIdleProcess</span><span style="font-family:宋体;">同样返回为</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:000000014027396B</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">rcx</span>, <span class="code-snippet__selector-attr">[rcx+510h]</span> ; <span class="code-snippet__selector-tag">eprocess-</span>&gt;<span class="code-snippet__selector-tag">job</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:0000000140273972</span> <span class="code-snippet__selector-tag">call</span>    <span class="code-snippet__selector-tag">PspGetJobSilo</span></span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    PspGetJobSilo</span><span style="font-family:宋体;">函数从当前进程的</span><span style="font-family:Calibri;">ejob</span><span style="font-family:宋体;">开始向父进程</span><span style="font-family:Calibri;">ejob</span><span style="font-family:宋体;">查找到第一个包含</span><span style="font-family:Calibri;">silo</span><span style="font-family:宋体;">状态的</span><span style="font-family:Calibri;">ejob</span><span style="font-family:宋体;">结构体。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:0000000140273977</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">rcx</span>, <span class="code-snippet__selector-tag">rax</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:000000014027397A</span> <span class="code-snippet__selector-tag">call</span>    <span class="code-snippet__selector-tag">PspIsSiloInSilo</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:000000014027397F</span> <span class="code-snippet__selector-tag">test</span>    <span class="code-snippet__selector-tag">al</span>, <span class="code-snippet__selector-tag">al</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:0000000140273981</span> <span class="code-snippet__selector-tag">setnz</span>   <span class="code-snippet__selector-tag">al</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:0000000140273984</span> <span class="code-snippet__selector-tag">jmp</span>     <span class="code-snippet__selector-tag">short</span> <span class="code-snippet__selector-tag">loc_140273953</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:0000000140273984</span> <span class="code-snippet__selector-tag">PsIsProcessInSilo</span> <span class="code-snippet__selector-tag">endp</span></span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    PspIsSiloInSilo</span><span style="font-family:宋体;">函数包含两个参数，第一个参数为目标进程包含</span><span style="font-family:Calibri;">silo</span><span style="font-family:宋体;">状态的</span><span style="font-family:Calibri;">ejob</span><span style="font-family:宋体;">结构体，第二个参数为当前进程的</span><span style="font-family:Calibri;">ejob</span><span style="font-family:宋体;">结构体。如果返回值不为</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">，则返回</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014064BB6C</span> <span class="code-snippet__selector-tag">PspIsSiloInSilo</span> <span class="code-snippet__selector-tag">proc</span> <span class="code-snippet__selector-tag">near</span> ; <span class="code-snippet__selector-tag">CODE</span> <span class="code-snippet__selector-tag">XREF</span>: <span class="code-snippet__selector-tag">PsIsProcessInSilo</span>+32↑<span class="code-snippet__selector-tag">p</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014064BB6C</span> ; <span class="code-snippet__selector-tag">PsIsThreadInSilo</span>+1<span class="code-snippet__selector-tag">EA483</span>↑<span class="code-snippet__selector-tag">p</span> ...</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014064BB6C</span> <span class="code-snippet__selector-tag">test</span>    <span class="code-snippet__selector-tag">rdx</span>, <span class="code-snippet__selector-tag">rdx</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014064BB6F</span> <span class="code-snippet__selector-tag">jnz</span>     <span class="code-snippet__selector-tag">short</span> <span class="code-snippet__selector-tag">loc_14064BB75</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014064BB71</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014064BB71</span> <span class="code-snippet__selector-tag">loc_14064BB71</span>: ; <span class="code-snippet__selector-tag">CODE</span> <span class="code-snippet__selector-tag">XREF</span>: <span class="code-snippet__selector-tag">PspIsSiloInSilo</span>+1<span class="code-snippet__selector-tag">BA6A7</span>↓<span class="code-snippet__selector-tag">j</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014064BB71</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">al</span>, 1</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014064BB73</span> <span class="code-snippet__selector-tag">retn</span></span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">	</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  如果第二个参数</span><span style="font-family:Calibri;">ejob</span><span style="font-family:宋体;">为</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">，则返回</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014064BB75</span> <span class="code-snippet__selector-tag">loc_14064BB75</span>: ; <span class="code-snippet__selector-tag">CODE</span> <span class="code-snippet__selector-tag">XREF</span>: <span class="code-snippet__selector-tag">PspIsSiloInSilo</span>+3↑<span class="code-snippet__selector-tag">j</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014064BB75</span> ; <span class="code-snippet__selector-tag">PspIsSiloInSilo</span>+1<span class="code-snippet__selector-tag">BA6B4</span>↓<span class="code-snippet__selector-tag">j</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014064BB75</span> <span class="code-snippet__selector-tag">test</span>    <span class="code-snippet__selector-tag">rcx</span>, <span class="code-snippet__selector-tag">rcx</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014064BB78</span> <span class="code-snippet__selector-tag">jnz</span>     <span class="code-snippet__selector-tag">loc_140806210</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014064BB7E</span> <span class="code-snippet__selector-tag">xor</span>     <span class="code-snippet__selector-tag">al</span>, <span class="code-snippet__selector-tag">al</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014064BB80</span> <span class="code-snippet__selector-tag">retn</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140806210</span> <span class="code-snippet__selector-tag">loc_140806210</span>: ; <span class="code-snippet__selector-tag">CODE</span> <span class="code-snippet__selector-tag">XREF</span>: <span class="code-snippet__selector-tag">PspIsSiloInSilo</span>+<span class="code-snippet__selector-tag">C</span>↑<span class="code-snippet__selector-tag">j</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140806210</span> <span class="code-snippet__selector-tag">cmp</span>     <span class="code-snippet__selector-tag">rcx</span>, <span class="code-snippet__selector-tag">rdx</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140806213</span> <span class="code-snippet__selector-tag">jz</span>      <span class="code-snippet__selector-tag">loc_14064BB71</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140806219</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">rcx</span>, <span class="code-snippet__selector-attr">[rcx+430h]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140806220</span> <span class="code-snippet__selector-tag">jmp</span>     <span class="code-snippet__selector-tag">loc_14064BB75</span></span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  通过一个循环遍历第一个参数及它的父进程</span><span style="font-family:Calibri;">ejob</span><span style="font-family:宋体;">是否和第二个参数相等，如果相等返回</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">，否则返回</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">。</span></span><span style="font-family: 宋体;font-size: 10.5pt;letter-spacing: 0.034em;">所以通过上述两个函数的分析，一个进程能否获取另一个进程的</span><span style="font-size: 10.5pt;letter-spacing: 0.034em;font-family: Calibri;">handle</span><span style="font-family: 宋体;font-size: 10.5pt;letter-spacing: 0.034em;">，有以下几种情况：</span></p><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;background:rgb(255,255,0);mso-highlight:rgb(255,255,0);"><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">、如果当前进程没有</span><span style="font-family:Calibri;">silo</span><span style="font-family:宋体;">结构，也就是说当前进程在容器外，是可以得到容器内进程的</span><span style="font-family:Calibri;">handle</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;background:rgb(255,255,0);mso-highlight:rgb(255,255,0);"><o:p></o:p></span></p><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;background:rgb(255,255,0);mso-highlight:rgb(255,255,0);"><span style="font-family:Calibri;">2</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">PsInitialSystemProcess</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">PsIdleProcess</span><span style="font-family:宋体;">进程能获取任何容器内进程的</span><span style="font-family:Calibri;">handle</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;background:rgb(255,255,0);mso-highlight:rgb(255,255,0);"><o:p></o:p></span></p><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;background:rgb(255,255,0);mso-highlight:rgb(255,255,0);"><span style="font-family:Calibri;">3</span><span style="font-family:宋体;">、容器内的进程是不能获取容器外的任何进程</span><span style="font-family:Calibri;">handle</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;background:rgb(255,255,0);mso-highlight:rgb(255,255,0);"><o:p></o:p></span></p><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;background:rgb(255,255,0);mso-highlight:rgb(255,255,0);"><span style="font-family:Calibri;">4</span><span style="font-family:宋体;">、只有父亲容器可以获取子容器内进程的</span><span style="font-family:Calibri;">handle</span><span style="font-family:宋体;">，反之不可以。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;background:rgb(255,255,0);mso-highlight:rgb(255,255,0);"><o:p></o:p></span></p><h3><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">2.4.3 </span><span style="font-family:宋体;">驱动隔离</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h3><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    silo</span><span style="font-family:宋体;">进程内不能安装和卸载驱动程序。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:0000000140399388</span> ; __<span class="code-snippet__selector-tag">int64</span> __<span class="code-snippet__selector-tag">fastcall</span> <span class="code-snippet__selector-tag">IopLoadDriverImage</span>(_<span class="code-snippet__selector-tag">OWORD</span> *)</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:0000000140399388</span> <span class="code-snippet__selector-tag">IopLoadDriverImage</span> <span class="code-snippet__selector-tag">proc</span> <span class="code-snippet__selector-tag">near</span> ; <span class="code-snippet__selector-tag">CODE</span> <span class="code-snippet__selector-tag">XREF</span>: <span class="code-snippet__selector-tag">NtLoadDriver</span>+4↓<span class="code-snippet__selector-tag">p</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:0000000140399388</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:00000001403993EE</span> <span class="code-snippet__selector-tag">call</span>    <span class="code-snippet__selector-tag">PsIsCurrentThreadInServerSilo</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:00000001403993F3</span> <span class="code-snippet__selector-tag">test</span>    <span class="code-snippet__selector-tag">al</span>, <span class="code-snippet__selector-tag">al</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.text</span><span class="code-snippet__selector-pseudo">:00000001403993F5</span> <span class="code-snippet__selector-tag">jnz</span>     <span class="code-snippet__selector-tag">loc_140399568</span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  如果进程在</span>container<span style="font-family:宋体;">内是不允许加载驱动程序的。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140762F24</span> <span class="code-snippet__selector-tag">IopUnloadDriver</span> <span class="code-snippet__selector-tag">proc</span> <span class="code-snippet__selector-tag">near</span> ; <span class="code-snippet__selector-tag">CODE</span> <span class="code-snippet__selector-tag">XREF</span>: <span class="code-snippet__selector-tag">PnpUnloadAttachedDriver</span>+<span class="code-snippet__selector-tag">A1</span>↑<span class="code-snippet__selector-tag">p</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140762F24</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140762FA2</span> <span class="code-snippet__selector-tag">call</span>    <span class="code-snippet__selector-tag">PsIsCurrentThreadInServerSilo</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140762FA7</span> <span class="code-snippet__selector-tag">test</span>    <span class="code-snippet__selector-tag">al</span>, <span class="code-snippet__selector-tag">al</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:0000000140762FA9</span> <span class="code-snippet__selector-tag">jnz</span>     <span class="code-snippet__selector-tag">loc_14081B8E9</span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  同理，</span>contianer<span style="font-family:宋体;">进程不能卸载驱动程序。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h3><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">2.4.4 </span><span style="font-family:宋体;">文件隔离</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h3><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">AGE</span><span class="code-snippet__selector-pseudo">:000000014068F290</span> <span class="code-snippet__selector-tag">ObpLookupObjectName</span> <span class="code-snippet__selector-tag">proc</span> <span class="code-snippet__selector-tag">near</span> ; <span class="code-snippet__selector-tag">CODE</span> <span class="code-snippet__selector-tag">XREF</span>: <span class="code-snippet__selector-tag">ObReferenceObjectByNameEx</span>+156↑<span class="code-snippet__selector-tag">p</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014068F290</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014068F4C6</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">edx</span>, <span class="code-snippet__selector-tag">cs</span><span class="code-snippet__selector-pseudo">:PsObjectDirectorySiloContextSlot</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014068F4CC</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-attr">[rbp+0C0h+var_D0]</span>, <span class="code-snippet__selector-tag">r8</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014068F4D0</span> <span class="code-snippet__selector-tag">lea</span>     <span class="code-snippet__selector-tag">r8</span>, <span class="code-snippet__selector-attr">[rbp+0C0h+var_D0]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014068F4D4</span> <span class="code-snippet__selector-tag">call</span>    <span class="code-snippet__selector-tag">PsGetPermanentSiloContext</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014068F4D9</span> <span class="code-snippet__selector-tag">test</span>    <span class="code-snippet__selector-tag">eax</span>, <span class="code-snippet__selector-tag">eax</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014068F4DB</span> <span class="code-snippet__selector-tag">jns</span>     <span class="code-snippet__selector-tag">loc_140835AE0</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">PAGE</span><span class="code-snippet__selector-pseudo">:000000014068F4E1</span> <span class="code-snippet__selector-tag">mov</span>     <span class="code-snippet__selector-tag">r14</span>, <span class="code-snippet__selector-tag">cs</span><span class="code-snippet__selector-pseudo">:ObpRootDirectoryObject</span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  如果在容器中则通过</span>PsGetPermanentSiloContext<span style="font-family:宋体;">获取</span><span style="font-family:Calibri;">root directory</span><span style="font-family:宋体;">， 否则使用</span><span style="font-family:Calibri;">ObpRootDirectoryObject</span><span style="font-family:宋体;">作为</span><span style="font-family:Calibri;">root directory</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="makefile"><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:00000001402772A0 PsGetPermanentSiloContext proc near ; CODE XREF: CmGetRootKeyObjectForSilo+17↓p</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:00000001402772A0 test    rcx, rcx</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:00000001402772A3 jnz     short loc_1402772DB</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:00000001402772A5 mov     rcx, cs:qword_140D23990</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:00000001402772AC</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:00000001402772AC loc_1402772AC: ; CODE XREF: PsGetPermanentSiloContext+42↓j</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:00000001402772AC mov     qword ptr [r8], 0</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:00000001402772B3 cmp     edx, 20h ; &#39; &#39;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:00000001402772B6 jnb     loc_14041937E</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:00000001402772BC</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:00000001402772BC loc_1402772BC: ; CODE XREF: PsGetPermanentSiloContext+1A20F9↓j</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:00000001402772BC mov     eax, edx</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:00000001402772BE add     rax, rax</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:00000001402772C1 mov     rcx, [rcx+rax*8+8]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:00000001402772C6 mov     rax, rcx</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:00000001402772C9 and     rax, 0FFFFFFFFFFFFFFFEh</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:00000001402772CD jz      short loc_1402772E4</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:00000001402772CF test    cl, 1</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:00000001402772D2 jz      short loc_1402772EB</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:00000001402772D4 mov     [r8], rax</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:00000001402772D7 xor     eax, eax</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:00000001402772D9 retn</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:00000001402772D9 ; ---------------------------------------------------------------------------</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:00000001402772DA db 0CCh</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:00000001402772DB ; ---------------------------------------------------------------------------</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:00000001402772DB</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:00000001402772DB loc_1402772DB: ; CODE XREF: PsGetPermanentSiloContext+3↑j</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:00000001402772DB mov     rcx, [rcx+518h]</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">.text:00000001402772E2 jmp     short loc_1402772AC</span></span></code></pre></section><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">    ejob-&gt;Storage[PsObjectDirectorySiloContextSlot].value<span style="font-family:宋体;">为当前容器的</span><span style="font-family:Calibri;">root directory</span><span style="font-family:宋体;">。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">   OBP_GET_SILO_ROOT_DIRECTORY_FROM_SILO<span style="font-family:宋体;">函数有同样的功能。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p><br/></p><p style="display: none;"><mp-style-type data-value="3"></mp-style-type></p>



<p><a href="2247483796">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=1b585129&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg4NjU1NDU4MA%3D%3D%26mid%3D2247483796%26idx%3D1%26sn%3D07e185a325441c0570b5996edc7d408d%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Fri, 01 Mar 2024 12:01:00 +0800</pubDate>
    </item>
    <item>
      <title>Windows代码签名机制分析</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg4NjU1NDU4MA==&amp;mid=2247483791&amp;idx=1&amp;sn=1f066b3ced7063dace9424f5ab782b63</link>
      <description>本文通过逆向工程分析了windows10的代码签名机制。</description>
      <content:encoded><![CDATA[<p>
原创 <span>wzt</span> <span>2024-02-28 15:32</span> <span style="display: inline-block;">上海</span>
</p>

<p>本文通过逆向工程分析了windows10的代码签名机制。</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=f8a93da5&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_jpg%2F4iaJia7Cvd3PA204s1aRf91Zycwa4qX1PafILia92W4wUeGRAeicwzUqiaglq4FbiaZsATwnXibufCPCib0wSlTAfE7hFA%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<h1><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;"><span style="font-family:Calibri;">1 </span><span style="font-family:宋体;">简介</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;"><o:p></o:p></span></strong></h1><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    Windows</span><span style="font-family:宋体;">在</span><span style="font-family:Calibri;">vista</span><span style="font-family:宋体;">版本时就已经提供了二进制代码签名机制，到</span><span style="font-family:Calibri;">win10</span><span style="font-family:宋体;">版本时代码签名机制进化的更加全面，从当初的内核校验深入到硬件虚拟化层校验（</span><span style="font-family:Calibri;">vbs</span><span style="font-family:宋体;">），管理员可以编写丰富的</span><span style="font-family:Calibri;">policy</span><span style="font-family:宋体;">支持不同粒度的校验等级，可以说</span><span style="font-family:Calibri;">windows</span><span style="font-family:宋体;">的代码签名要比</span><span style="font-family:Calibri;">ios</span><span style="font-family:宋体;">更加细致与完善。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h1><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;"><span style="font-family:Calibri;">2 </span><span style="font-family:宋体;">代码签名原理</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:22.0000pt;mso-font-kerning:22.0000pt;"><o:p></o:p></span></strong></h1><h2><strong><span style="font-family: 宋体;font-size: 18pt;">2.1 签名信息的等级</span></strong><strong><span style="font-family: 宋体;font-size: 18pt;"><o:p></o:p></span></strong></h2><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">    Ios</span><span style="font-family:宋体;">及</span><span style="font-family:Calibri;">android</span><span style="font-family:宋体;">的某些版本是通过比较二进制程序的</span><span style="font-family:Calibri;">hash</span><span style="font-family:宋体;">值来做校验的，而</span><span style="font-family:Calibri;">windows</span><span style="font-family:宋体;">提供了更加丰富的校验等级，在微软的</span></span><span style="text-decoration:underline;"><span style="font-family: 宋体;color: rgb(0, 0, 255);"><span style="font-family:Calibri;">WDAC</span></span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">文档中，提供了如下的等级分类：</span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100000138" data-ratio="0.8953703703703704" data-s="300,640" style="" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=57463b68&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_png%2F4iaJia7Cvd3PA204s1aRf91Zycwa4qX1PaapBQHvSG5xlJeFD2iaZ231KwFCejIN5UkEUs0Y7icws8nwVm3QvVQecA%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100000139" data-ratio="0.7287037037037037" data-s="300,640" style="" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=e2aa4e98&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_png%2F4iaJia7Cvd3PA204s1aRf91Zycwa4qX1PanageA6w8kib5sv06iciaZy4GIobXV1erw1ib7879ONvXekXw3KXKB0qvog%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p style=""><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  可以看到除了使用</span><span style="font-family:Calibri;">hash</span><span style="font-family:宋体;">值，还可以使用文件名、文件路径、证书的发布者等等种类进行校验。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h2><strong><span style="font-family: 宋体;font-size: 18pt;">2.2 签名的存储结构</span></strong><strong><span style="font-family: 宋体;font-size: 18pt;"><o:p></o:p></span></strong></h2><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">     Windows</span><span style="font-family:宋体;">的签名信息可以存储在两个地方：</span><span style="font-family:Calibri;">PE</span><span style="font-family:宋体;">文件和</span><span style="font-family:Calibri;">catalog</span><span style="font-family:宋体;">文件。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h3><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">2.2.1 PE</span><span style="font-family:宋体;">文件签名信息</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h3><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  在</span><span style="font-family:Calibri;">PE</span><span style="font-family:宋体;">文件的</span><span style="font-family:Calibri;">Optional header</span><span style="font-family:宋体;">里加入一个</span><span style="font-family:Calibri;">Security Data Directory</span><span style="font-family:宋体;">：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100000131" data-ratio="0.1175925925925926" data-s="300,640" style="" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=efebc030&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_png%2F4iaJia7Cvd3PA204s1aRf91Zycwa4qX1Pa0sHWb1dC71gHSOEjerwB1vwsuibLbN20uCiaGuSaZJibCOAlDFIibmMPng%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><span style="letter-spacing: 0.034em;font-family: 宋体;font-size: 10.5pt;">  它指向<span style="font-family:Calibri;">Section</span>末尾的<span style="font-family:Calibri;">Attribute Certificate Table</span>存储签名信息，它的结构体在</span><span style="text-decoration: underline;"><span style="font-family: 宋体;color: rgb(0, 0, 255);"><span style="font-family:Calibri;">wintrust.h</span></span></span><span style="letter-spacing: 0.034em;font-family: 宋体;font-size: 10.5pt;">中定义：</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="properties"><code><span class="code-snippet_outer"><span class="code-snippet__attr">typedef</span> <span class="code-snippet__string">struct _WIN_CERTIFICATE {</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">DWORD</span> <span class="code-snippet__string">dwLength;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">WORD</span>  <span class="code-snippet__string">wRevision;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">WORD</span>  <span class="code-snippet__string">wCertificateType;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">BYTE</span>  <span class="code-snippet__string">bCertificate[ANYSIZE_ARRAY];</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">}</span> <span class="code-snippet__string">WIN_CERTIFICATE, *LPWIN_CERTIFICATE;</span></span></code></pre></section><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100000132" data-ratio="0.3907407407407407" data-s="300,640" style="" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=2e53dd2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_png%2F4iaJia7Cvd3PA204s1aRf91Zycwa4qX1PaE0WSbHhlb5t5K1biaBDe4BXuS3qUOvxbiaM7TkPgnn00omP4ccbXw2sg%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">签名结构架构如下：</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"> </span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100000133" data-ratio="1.1583333333333334" data-s="300,640" style="" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=4735713e&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_png%2F4iaJia7Cvd3PA204s1aRf91Zycwa4qX1PaybgyC6G6wiaicqFicDFWANauXLDpblOGuw12jmpEwUHsQbe5XM5g4AvKA%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">       WIN_CERTIFICATE</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">结构体的</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">bCertificate</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">指向具体的签名信息，它是一个</span><span style="font-family:Calibri;">pkcs#7</span><span style="font-family:宋体;">结构。</span><span style="font-family:Calibri;">ContantInfo</span><span style="font-family:宋体;">里保存了当前文件的</span><span style="font-family:Calibri;">hash</span><span style="font-family:宋体;">值， </span><span style="font-family:Calibri;">windows</span><span style="font-family:宋体;">支持两种格式的</span><span style="font-family:Calibri;">hash</span><span style="font-family:宋体;">：一个是文件的整个</span><span style="font-family:Calibri;">hash</span><span style="font-family:宋体;">值，另一种是已</span><span style="font-family:Calibri;">PAGE</span><span style="font-family:宋体;">为单位的</span><span style="font-family:Calibri;">hash</span><span style="font-family:宋体;">值。</span><span style="font-family:Calibri;">IOS</span><span style="font-family:宋体;">的代码签名机制只允许以页为单位的</span><span style="font-family:Calibri;">hash</span><span style="font-family:宋体;">值校验，那么当一个文件非常大时，签名信息里就要携带非常大的</span><span style="font-family:Calibri;">hash</span><span style="font-family:宋体;">值，会使文件体积变得更大。在笔者的</span><span style="font-family:Calibri;">win10</span><span style="font-family:宋体;">系统中，几乎所有的</span><span style="font-family:Calibri;">pe</span><span style="font-family:宋体;">文件都只携带了文件的</span><span style="font-family:Calibri;">hash</span><span style="font-family:宋体;">值。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">   已</span><span style="font-family:Calibri;">smss.exe</span><span style="font-family:宋体;">为例，右键点击属性，如果文件有签名信息，可以看到有数字签名一栏，点击查看证书信息：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100000134" data-ratio="0.7302631578947368" data-s="300,640" style="" data-type="png" data-w="912" src="https://wechat2rss.xlab.app/img-proxy/?k=0bb8b5ae&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_png%2F4iaJia7Cvd3PA204s1aRf91Zycwa4qX1Pat5fO8sTzM5aiciax20etqz5zy0OsYpJllwULRARbGfYKPEHASGBkqjTA%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  序列号为文件的</span><span style="font-family:Calibri;">hash</span><span style="font-family:宋体;">值，采用</span><span style="font-family:Calibri;">sha256</span><span style="font-family:宋体;">算法。</span></span></p><p><span style="font-family: 宋体;font-size: 10.5pt;letter-spacing: 0.034em;">  在笔者的</span><span style="font-size: 10.5pt;letter-spacing: 0.034em;font-family: Calibri;">win10</span><span style="font-family: 宋体;font-size: 10.5pt;letter-spacing: 0.034em;">系统中，并不是所有的二进制都做了签名信息，微软公司只对重要的系统文件加了签名信息。</span></p><h3><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">2.2.2 </span><span style="font-family:宋体;">文件</span><span style="font-family:Calibri;">hash</span><span style="font-family:宋体;">值的计算方法</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h3><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  文件</span><span style="font-family:Calibri;">hash</span><span style="font-family:宋体;">值的计算并不是计算所有的文件内容，需要去掉</span><span style="font-family:Calibri;">pe</span><span style="font-family:宋体;">文件中与签名有关的数据，以下算法来自微软的官方文档：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100000140" data-ratio="0.5981481481481481" data-s="300,640" style="" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=4dea3e02&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_png%2F4iaJia7Cvd3PA204s1aRf91Zycwa4qX1Pa8arEBysAJnyASJCBKFRXBpYulLHU5fiap47ulia4t3lxnqxUuBBCwnfg%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100000141" data-ratio="0.9703703703703703" data-s="300,640" style="" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=f91cd064&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_png%2F4iaJia7Cvd3PA204s1aRf91Zycwa4qX1PaKggzO2lia6GeMJjiaf7l9mtziaaicZe4S4ibiamfS5Y6LUongma2rdf3r19Q%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p style="margin-right:0.0000pt;mso-para-margin-right:0.0000gd;mso-para-margin-left:0.0000gd;mso-pagination:widow-orphan;"><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:Arial;font-size:11.0000pt;mso-font-kerning:0.0000pt;"></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:Arial;font-size:11.0000pt;mso-font-kerning:0.0000pt;"><span style="font-family:宋体;">  同时</span><span style="font-family:Calibri;">windows api</span><span style="font-family:宋体;">还提供了一系列关于签名的辅助函数：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:Arial;font-size:11.0000pt;mso-font-kerning:0.0000pt;"><o:p></o:p></span></p><h2 style="margin-top:12.0000pt;margin-right:0.0000pt;margin-bottom:4.5000pt;margin-left:0.0000pt;padding:0pt 0pt 0pt 0pt;mso-pagination:widow-orphan;mso-line-height-alt:12pt;"><strong><span style="text-decoration:underline;"><span style="font-family: 宋体;color: rgb(0, 0, 255);letter-spacing: 0pt;background: rgb(255, 255, 255);">Image Integrity</span></span></strong><strong><span style="font-family: 宋体;font-size: 18pt;"><o:p></o:p></span></strong></h2><p style="margin-left: 0pt;padding: 0pt;background: rgb(255, 255, 255);"><span style="font-family: &#34;Segoe UI&#34;;color: rgb(22, 22, 22);letter-spacing: 0pt;font-size: 10.5pt;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;">The image integrity functions manage the set of certificates in an image file.</span><span style="font-family: &#34;Segoe UI&#34;;color: rgb(22, 22, 22);letter-spacing: 0pt;font-size: 10.5pt;"><o:p></o:p></span></p><p style="padding:0pt 0pt 0pt 0pt;mso-pagination:widow-orphan;"><strong><span style="font-family: &#34;Segoe UI&#34;;color: rgb(0, 0, 255);letter-spacing: 0pt;font-size: 10.5pt;background: rgb(255, 255, 255);">DigestFunction</span></strong><span style="font-family: &#34;Segoe UI&#34;;color: rgb(22, 22, 22);letter-spacing: 0pt;font-size: 10.5pt;background: rgb(255, 255, 255);"><br/></span><strong><span style="font-family: &#34;Segoe UI&#34;;color: rgb(0, 0, 255);letter-spacing: 0pt;font-size: 10.5pt;background: rgb(255, 255, 255);">ImageAddCertificate</span></strong><span style="font-family: &#34;Segoe UI&#34;;color: rgb(22, 22, 22);letter-spacing: 0pt;font-size: 10.5pt;background: rgb(255, 255, 255);"><br/></span><strong><span style="font-family: &#34;Segoe UI&#34;;color: rgb(0, 0, 255);letter-spacing: 0pt;font-size: 10.5pt;background: rgb(255, 255, 255);">ImageEnumerateCertificates</span></strong><span style="font-family: &#34;Segoe UI&#34;;color: rgb(22, 22, 22);letter-spacing: 0pt;font-size: 10.5pt;background: rgb(255, 255, 255);"><br/></span><strong><span style="font-family: &#34;Segoe UI&#34;;color: rgb(0, 0, 255);letter-spacing: 0pt;font-size: 10.5pt;background: rgb(255, 255, 255);">ImageGetCertificateData</span></strong><span style="font-family: &#34;Segoe UI&#34;;color: rgb(22, 22, 22);letter-spacing: 0pt;font-size: 10.5pt;background: rgb(255, 255, 255);"><br/></span><strong><span style="font-family: &#34;Segoe UI&#34;;color: rgb(0, 0, 255);letter-spacing: 0pt;font-size: 10.5pt;background: rgb(255, 255, 255);">ImageGetCertificateHeader</span></strong><span style="font-family: &#34;Segoe UI&#34;;color: rgb(22, 22, 22);letter-spacing: 0pt;font-size: 10.5pt;background: rgb(255, 255, 255);"><br/></span><strong><span style="font-family: &#34;Segoe UI&#34;;color: rgb(0, 0, 255);letter-spacing: 0pt;font-size: 10.5pt;background: rgb(255, 255, 255);">ImageGetDigestStream</span></strong><span style="font-family: &#34;Segoe UI&#34;;color: rgb(22, 22, 22);letter-spacing: 0pt;font-size: 10.5pt;background: rgb(255, 255, 255);"><br/></span><strong><span style="font-family: &#34;Segoe UI&#34;;color: rgb(0, 0, 255);letter-spacing: 0pt;font-size: 10.5pt;background: rgb(255, 255, 255);">ImageRemoveCertificate</span></strong><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:0.0000pt;"><o:p></o:p></span></p><h3><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">2.2.3 Catalog</span><span style="font-family:宋体;">文件</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h3><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  将文件签名信息保存在</span><span style="font-family:Calibri;">pe</span><span style="font-family:宋体;">文件中，就会变得不是很灵活，为此微软公司提供了另一种签名信息的存储格式</span><span style="font-family:Calibri;">catalog</span><span style="font-family:宋体;">文件类型，并提供了一些内核</span><span style="font-family:Calibri;">api</span><span style="font-family:宋体;">可以动态增加或删除一个文件的签名信息， 结合前面提到的</span><span style="font-family:Calibri;">WDAC policy</span><span style="font-family:宋体;">就会变得更加灵活，在稍后的章节中会详细介绍。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h2><strong><span style="font-family: 宋体;font-size: 18pt;">2.3 签名的校验逻辑</span></strong><strong><span style="font-family: 宋体;font-size: 18pt;"><o:p></o:p></span></strong></h2><h3><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">2.3.1 </span><span style="font-family:宋体;">代码签名的初始化</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h3><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  由于</span><span style="font-family:Calibri;">win10</span><span style="font-family:宋体;">启动了</span><span style="font-family:Calibri;">WDAC policy</span><span style="font-family:宋体;">策略</span><span style="font-family:Calibri;">SIPolicy.p7b</span><span style="font-family:宋体;">，它是一个</span><span style="font-family:Calibri;">pkcs#7</span><span style="font-family:宋体;">格式的文件，它由</span><span style="font-family:Calibri;">windows loader</span><span style="font-family:宋体;">加载并解析，然后在传给</span><span style="font-family:Calibri;">nt</span><span style="font-family:宋体;">内核。德国</span></span><span style="text-decoration:underline;"><span style="font-family: 宋体;color: rgb(0, 0, 255);"><span style="font-family:Calibri;">bsi</span></span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">的安全研究人员已经对其启动过程做了详细的分析，强烈推荐大家仔细阅读，</span><span style="font-family:Calibri;">windows loader</span><span style="font-family:宋体;">除了加载</span><span style="font-family:Calibri;">wdac policy</span><span style="font-family:宋体;">外，还要加载</span><span style="font-family:Calibri;">ci.dll</span><span style="font-family:宋体;">，因为</span><span style="font-family:Calibri;">Windows</span><span style="font-family:宋体;">的签名代码逻辑基本都在</span><span style="font-family:Calibri;">ci.dll</span><span style="font-family:宋体;">中实现。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">可以看到它导出了以下函数：</span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100000142" data-ratio="0.3572815533980582" data-s="300,640" style="" data-type="png" data-w="1030" src="https://wechat2rss.xlab.app/img-proxy/?k=52b3bb74&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_png%2F4iaJia7Cvd3PA204s1aRf91Zycwa4qX1PaF7PDtQsC4xv1Pia2YWl4iaTDHib9WhEqHFicw8PcBwFZtVkiauvROb1MUJw%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><h2 style="margin-left:0.0000pt;text-indent:21.0000pt;mso-char-indent-count:0.0000;mso-pagination:widow-orphan;"><span style="text-decoration:underline;"><span style="font-family: Calibri;color: rgb(0, 0, 255);font-size: 10.5pt;">cybereason.</span></span><span style="text-decoration:underline;"><span style="font-family: 宋体;color: rgb(0, 0, 255);font-size: 10.5pt;"><span style="font-family:Calibri;">com</span></span></span><span style="font-family: 宋体;font-size: 10.5pt;"><span style="font-family:宋体;">的安全研究人员给出了一篇非常棒的</span><span style="font-family:Calibri;">paper</span><span style="font-family:宋体;">解析了</span><span style="font-family:Calibri;">CiCheckSignedFile</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">CiValidateFileObject</span><span style="font-family:宋体;">两个函数的用法，还原了它们的参数和部分数据结构体，同时在</span><span style="font-family:Calibri;">github</span><span style="font-family:宋体;">提供了一个</span></span><span style="text-decoration:underline;"><span style="font-family: 宋体;color: rgb(0, 0, 255);font-size: 10.5pt;"><span style="font-family:Calibri;">demo</span></span></span><span style="font-family: 宋体;font-size: 10.5pt;"><span style="font-family:宋体;">使得一个驱动程序链接</span><span style="font-family:Calibri;">ci.dll</span><span style="font-family:宋体;">，调用上述两个函数对一个文件的签名信息进行校验的例子。</span></span><span style="font-family: 宋体;font-size: 10.5pt;"><o:p></o:p></span></h2><p><span style="font-family: 宋体;font-size: 10.5pt;"><span style="font-family:宋体;">在笔者的</span><span style="font-family:Calibri;">win10</span><span style="font-family:宋体;">系统中，没有发现内核有调用这两个接口，但是内核在初始化中调用了</span><span style="font-family:Calibri;">CiInitialize</span><span style="font-family:宋体;">函数进行了代码签名的初始化工作：</span></span><span style="font-family: 宋体;font-size: 10.5pt;"><o:p></o:p></span></p><p><span style="font-family: Calibri;font-size: 10.5pt;">InitBootProcessor</span><span style="font-family: 宋体;font-size: 10.5pt;"><span style="font-family:Calibri;">-&gt;</span></span><span style="font-family: Calibri;font-size: 10.5pt;">SeInitSystem</span><span style="font-family: 宋体;font-size: 10.5pt;"><span style="font-family:Calibri;">-&gt;</span></span><span style="font-family: Calibri;font-size: 10.5pt;">SepInitializationPhase1</span><span style="font-family: 宋体;font-size: 10.5pt;"><span style="font-family:Calibri;">-&gt;SepInitializeCodeIntegrity:</span></span><span style="font-family: 宋体;font-size: 10.5pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">__<span class="code-snippet__function">int64 <span class="code-snippet__title">SepInitializeCodeIntegrity</span><span class="code-snippet__params">()</span></span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">int</span> v0; <span class="code-snippet__comment">// edi</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">__int64 v1; <span class="code-snippet__comment">// rbx</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">__int64 v2; <span class="code-snippet__comment">// rcx</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">int</span> *v3; <span class="code-snippet__comment">// rdx</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">v0 = <span class="code-snippet__number">6</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__built_in">memset</span>(&amp;unk_140C373C4, <span class="code-snippet__number">0</span>, <span class="code-snippet__number">0xEC</span>ui64);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">v1 = <span class="code-snippet__number">0</span>i64;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">SeCiCallbacks = <span class="code-snippet__number">0xF8</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">qword_140C374B0 = <span class="code-snippet__number">0xA00000C</span>i64;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> ( KeLoaderBlock_0 )</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">v2 = *(_QWORD *)(KeLoaderBlock_0 + <span class="code-snippet__number">240</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> ( v2 )</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">v3 = *(<span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">int</span> **)(v2 + <span class="code-snippet__number">2904</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> ( v3 )</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">v0 = *v3;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> ( *(_QWORD *)(KeLoaderBlock_0 + <span class="code-snippet__number">216</span>) &amp;&amp; (<span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">int</span>)SepIsOptionPresent() )</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">SeCiDebugOptions |= <span class="code-snippet__number">1u</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> ( KeLoaderBlock_0 )</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">v1 = KeLoaderBlock_0 + <span class="code-snippet__number">48</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">return</span> CiInitialize(v0, v1, &amp;SeCiCallbacks, &amp;SeCiPrivateApis);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family: 宋体;font-size: 10.5pt;"><span style="font-family:Calibri;">    Nt</span><span style="font-family:宋体;">内核向</span><span style="font-family:Calibri;">ci.dll</span><span style="font-family:宋体;">传递了</span></span><span style="font-family: Calibri;color: rgb(0, 0, 0);font-size: 10.5pt;">SeCiCallbacks</span><span style="font-family: 宋体;color: rgb(0, 0, 0);font-size: 10.5pt;">数组，写入了一系列回调函数：</span><span style="font-family: Calibri;font-size: 10.5pt;background: rgb(255, 255, 0);"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="markdown"><code><span class="code-snippet_outer"><span class="code-snippet__strong">__int64 __</span>fastcall CipInitialize(<span class="code-snippet__strong">__int64 a1, const UNICODE_STRING **</span>a2, <span class="code-snippet__strong">__int64 a3, __</span>int64 a4)</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__emphasis">*(_QWORD *</span>)(a3 + 0x20) = CiValidateImageHeader;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__emphasis">*(_QWORD *</span>)(a3 + 0x28) = CiValidateImageData;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__emphasis">*(_QWORD *</span>)(a3 + 24) = CiQueryInformation;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__emphasis">*(_QWORD *</span>)(a3 + 8) = CiSetFileCache;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__emphasis">*(_QWORD *</span>)(a3 + 16) = CiGetFileCache;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__emphasis">*(_QWORD *</span>)(a3 + 48) = CiHashMemory;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__emphasis">*(_QWORD *</span>)(a3 + 56) = KappxIsPackageFile;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__emphasis">*(_QWORD *</span>)(a3 + 64) = CiCompareSigningLevels;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__emphasis">*(_QWORD *</span>)(a3 + 72) = CiValidateFileAsImageType;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__emphasis">*(_QWORD *</span>)(a3 + 80) = CiRegisterSigningInformation;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__emphasis">*(_QWORD *</span>)(a3 + 88) = CiUnregisterSigningInformation;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__emphasis">*(_QWORD *</span>)(a3 + 96) = CiInitializePolicy;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__emphasis">*(_QWORD *</span>)(a3 + 0x88) = CipQueryPolicyInformation;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__emphasis">*(_QWORD *</span>)(a3 + 144) = CiQuerySecurityPolicy;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__emphasis">*(_QWORD *</span>)(a3 + 152) = CiRevalidateImage;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__emphasis">*(_QWORD *</span>)(a3 + 160) = CiSetInformation;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__emphasis">*(_QWORD *</span>)(a3 + 168) = CiSetInformationProcess;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__emphasis">*(_QWORD *</span>)(a3 + 176) = CiGetBuildExpiryTime;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__emphasis">*(_QWORD *</span>)(a3 + 184) = &amp;CiCheckProcessDebugAccessPolicy;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__emphasis">*(_QWORD *</span>)(a3 + 192) = CiGetCodeIntegrityOriginClaimForFileObject;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__emphasis">*(_QWORD *</span>)(a3 + 200) = CiDeleteCodeIntegrityOriginClaimMembers;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__emphasis">*(_QWORD *</span>)(a3 + 208) = CiDeleteCodeIntegrityOriginClaimForFileObject;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__emphasis">*(_QWORD *</span>)(a3 + 224) = CiCompareExistingSePool;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__emphasis">*(_QWORD *</span>)(a3 + 232) = CiSetCachedOriginClaim;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">if ( !v19 )</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__emphasis">*(_QWORD *</span>)(a3 + 120) = CiGetStrongImageReference;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__emphasis">*(_QWORD *</span>)(a3 + 104) = CiReleaseContext;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__emphasis">*(_QWORD *</span>)(a3 + 128) = CiHvciSetImageBaseAddress;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__emphasis">*(_QWORD *</span>)(a3 + 216) = CiHvciReportMmIncompatibility;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family: 宋体;font-size: 10.5pt;">  可以看到</span><span style="font-family: 宋体;font-size: 10.5pt;"><span style="font-family:Calibri;">CiCheckSignedFile</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">CiValidateFileObject</span></span><span style="font-family: 宋体;font-size: 10.5pt;"><span style="font-family:宋体;">这两个函数并没有写入回调数组，说明</span><span style="font-family:Calibri;">nt</span><span style="font-family:宋体;">在代码签名校验时是没有使用这两个函数的。相反，</span><span style="font-family:Calibri;">nt</span><span style="font-family:宋体;">内核使用</span></span><span style="font-family: Calibri;font-size: 10.5pt;">CiValidateImageHeader</span><span style="font-family: 宋体;font-size: 10.5pt;">和</span><span style="font-family: Calibri;font-size: 10.5pt;">CiValidateImageData</span><span style="font-family: 宋体;font-size: 10.5pt;"><span style="font-family:宋体;">两个函数做签名校验，一个用来做文件</span><span style="font-family:Calibri;">hash</span><span style="font-family:宋体;">的完整性校验，一个用来做</span><span style="font-family:Calibri;">page</span><span style="font-family:宋体;">的完整性校验。</span></span><span style="font-family: 宋体;font-size: 10.5pt;"><o:p></o:p></span></p><h3><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">2.3.2 </span><span style="font-family:宋体;">文件</span><span style="font-family:Calibri;">hash</span><span style="font-family:宋体;">校验逻辑</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:16.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h3><h4><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:14.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">2.3.2.1 </span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:Arial;mso-fareast-font-family:黑体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:14.0000pt;mso-font-kerning:1.0000pt;">CiValidateImageHeader</span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:14.0000pt;mso-font-kerning:1.0000pt;">逻辑</span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:Arial;mso-fareast-font-family:黑体;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:14.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h4><p><span style="font-family: 宋体;font-size: 10.5pt;">  在</span><span style="font-family: Calibri;font-size: 10.5pt;">CiValidateImageHeader</span><span style="font-family: 宋体;font-size: 10.5pt;">处下个断点：</span><span style="font-family: Calibri;font-size: 10.5pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="http"><code><span class="code-snippet_outer"><span class="code-snippet__attribute">3</span>: kd&gt; k</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"># Child-SP          RetAddr               Call Site</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__number">00</span> ffff940b<span class="code-snippet__string">`9de071b8 fffff803`</span><span class="code-snippet__number">74453</span>ec1 CI!CiValidateImageHeader</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__number">01</span> ffff940b<span class="code-snippet__string">`9de071c0 fffff803`</span><span class="code-snippet__number">7445435</span>c nt!SeValidateImageHeader+<span class="code-snippet__number">0xd9</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__number">02</span> ffff940b<span class="code-snippet__string">`9de07270 fffff803`</span><span class="code-snippet__number">744f</span>377c nt!MiValidateSectionCreate+<span class="code-snippet__number">0x438</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__number">03</span> ffff940b<span class="code-snippet__string">`9de07450 fffff803`</span><span class="code-snippet__number">74458862</span> nt!MiValidateSectionSigningPolicy+<span class="code-snippet__number">0xac</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__number">04</span> ffff940b<span class="code-snippet__string">`9de074b0 fffff803`</span><span class="code-snippet__number">744f</span>59eb nt!MiCreateNewSection+<span class="code-snippet__number">0x59a</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__number">05</span> ffff940b<span class="code-snippet__string">`9de07610 fffff803`</span><span class="code-snippet__number">744f</span>5034 nt!MiCreateImageOrDataSection+<span class="code-snippet__number">0x2d</span>b</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__number">06</span> ffff940b<span class="code-snippet__string">`9de07700 fffff803`</span><span class="code-snippet__number">744</span>c7222 nt!MiCreateSection+<span class="code-snippet__number">0xf4</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__number">07</span> ffff940b<span class="code-snippet__string">`9de07880 fffff803`</span><span class="code-snippet__number">7458848d</span> nt!MmCreateSpecialImageSection+<span class="code-snippet__number">0xc6</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__number">08</span> ffff940b<span class="code-snippet__string">`9de07930 fffff803`</span><span class="code-snippet__number">74588371</span> nt!PspLocateSystemDll+<span class="code-snippet__number">0xe1</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__number">09</span> ffff940b<span class="code-snippet__string">`9de079f0 fffff803`</span><span class="code-snippet__number">7483</span>ebc7 nt!PsLocateSystemDlls+<span class="code-snippet__number">0x4d</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__number">0</span>a ffff940b<span class="code-snippet__string">`9de07a30 fffff803`</span><span class="code-snippet__number">74862301</span> nt!IoInitSystemPreDrivers+<span class="code-snippet__number">0xbe7</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__number">0</span>b ffff940b<span class="code-snippet__string">`9de07b70 fffff803`</span><span class="code-snippet__number">745</span>a86ab nt!IoInitSystem+<span class="code-snippet__number">0x15</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__number">0</span>c ffff940b<span class="code-snippet__string">`9de07ba0 fffff803`</span><span class="code-snippet__number">74055485</span> nt!Phase1Initialization+<span class="code-snippet__number">0x3b</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__number">0d</span> ffff940b<span class="code-snippet__string">`9de07bd0 fffff803`</span><span class="code-snippet__number">74202</span>cc8 nt!PspSystemThreadStartup+<span class="code-snippet__number">0x55</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__number">0</span>e ffff940b<span class="code-snippet__string">`9de07c20 00000000`</span><span class="code-snippet__number">00000000</span> nt!KiStartSystemThread+<span class="code-snippet__number">0x28</span></span></code></pre></section><p><span style="font-family: Calibri;font-size: 10.5pt;">    MiCreateSection</span><span style="font-family: 宋体;font-size: 10.5pt;"><span style="font-family:宋体;">建立</span><span style="font-family:Calibri;">section</span><span style="font-family:宋体;">的路径中会调用</span></span><span style="font-family: Calibri;font-size: 10.5pt;">CiValidateImageHeader</span><span style="font-family: 宋体;font-size: 10.5pt;"><span style="font-family:宋体;">做文件</span><span style="font-family:Calibri;">hash</span><span style="font-family:宋体;">校验，它的大致流程如下：</span></span><span style="font-family: Calibri;font-size: 10.5pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="properties"><code><span class="code-snippet_outer"><span class="code-snippet__attr">CiValidateImageHeader()</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">{</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">If</span> <span class="code-snippet__string">(CipIsFileInUMCIExclusionPaths())</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">Return</span> <span class="code-snippet__string">;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">ActionsForImage</span> = <span class="code-snippet__string">CiGetActionsForImage(v93, (__int64)v28, v29, v32);</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">if</span> <span class="code-snippet__string">( (ActionsForImage &amp; 1) != 0 )</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">{</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">CipValidateFileInCache()</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">}</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">if</span> <span class="code-snippet__string">( (ActionsForImage &amp; 0x40) != 0 )</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">{</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">nt!MmGetImageFileSignatureInformation()</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">}</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">if</span> <span class="code-snippet__string">( (ActionsForImage &amp; 0x100) != 0 )</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">{</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">CipValidateImageHash(CipValidateFileHash,</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">}</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">if</span> <span class="code-snippet__string">( (ActionsForImage &amp; 4) != 0 )</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">{</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">CipValidateImageHash(CipValidatePageHash,</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">}</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">}</span></span></code></pre></section><p><span style="font-family: 宋体;font-size: 10.5pt;"><span style="font-family:宋体;">  首先调用</span><span style="font-family:Calibri;">CipIsFileInUMCIExclusionPaths</span><span style="font-family:宋体;">，这个函数是</span><span style="font-family:Calibri;">win11</span><span style="font-family:宋体;">新增的用于开发者模式的白名单功能，它维护了一个列表，在列表中的</span><span style="font-family:Calibri;">path</span><span style="font-family:宋体;">可以不用做校验。</span></span><span style="font-family: 宋体;font-size: 10.5pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">char</span> __<span class="code-snippet__function">fastcall <span class="code-snippet__title">CipIsFileInUMCIExclusionPaths</span><span class="code-snippet__params">(__int64 a1)</span></span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">char</span> result; <span class="code-snippet__comment">// al</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">char</span> v2; <span class="code-snippet__comment">// bl</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">int</span> v3; <span class="code-snippet__comment">// edi</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">const</span> UNICODE_STRING *v4; <span class="code-snippet__comment">// rsi</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">result = g_CiExclusionListCount;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">v2 = <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> ( g_CiExclusionListCount )</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">v3 = <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> ( g_CiExclusionListCount )</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">v4 = (<span class="code-snippet__keyword">const</span> UNICODE_STRING *)(a1 + <span class="code-snippet__number">88</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">while</span> ( !RtlPrefixUnicodeString((PCUNICODE_STRING)(g_CiExclusionList + <span class="code-snippet__number">0x10</span>i64 * v3), v4, <span class="code-snippet__number">1u</span>) )</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> ( ++v3 &gt;= g_CiExclusionListCount )</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">return</span> v2;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">return</span> <span class="code-snippet__number">1</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">return</span> v2;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">return</span> result;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family: 宋体;font-size: 10.5pt;"><span style="font-family:宋体;">在笔者的</span><span style="font-family:Calibri;">win11</span><span style="font-family:宋体;">版本中，这个列表为空：</span></span><span style="font-family: 宋体;font-size: 10.5pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="http"><code><span class="code-snippet_outer"><span class="code-snippet__attribute">4</span>: kd&gt; p</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">CI!CipIsFileInUMCIExclusionPaths+0xf:</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">fffff801`7f6f7ac3 8b053795feff mov     eax,dword ptr [CI!g_CiExclusionListCount (fffff801`7f6e1000)]</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">4: kd&gt;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">CI!CipIsFileInUMCIExclusionPaths+0x15:</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">fffff801`7f6f7ac9 33db xor     ebx,ebx</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">4: kd&gt; r rax</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">rax=0000000000000000</span></code></pre></section><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">  然后调用</span><span style="font-family: Calibri;font-size: 10.5pt;">CiGetActionsForImage</span><span style="font-family: 宋体;font-size: 10.5pt;">得到要执行的动作，</span><span style="font-family: Calibri;font-size: 10.5pt;">ActionsForImage &amp; 1</span><span style="font-family: 宋体;font-size: 10.5pt;"><span style="font-family:宋体;">表示在签名的</span><span style="font-family:Calibri;">cache</span><span style="font-family:宋体;">中校验，否则</span></span><span style="font-family: Calibri;font-size: 10.5pt;">ActionsForImage &amp; 0x40</span><span style="font-family: 宋体;font-size: 10.5pt;">表示从文件中提取签名信息。进一步</span><span style="font-family: Calibri;font-size: 10.5pt;">ActionsForImage &amp; 0x100</span><span style="font-family: 宋体;font-size: 10.5pt;"><span style="font-family:宋体;">表示对文件</span><span style="font-family:Calibri;">hash</span><span style="font-family:宋体;">做校验，</span></span><span style="font-family: Calibri;font-size: 10.5pt;">ActionsForImage &amp; 4</span><span style="font-family: 宋体;font-size: 10.5pt;"><span style="font-family:宋体;">表示对文件的</span><span style="font-family:Calibri;">page</span><span style="font-family:宋体;">做</span><span style="font-family:Calibri;">hash</span><span style="font-family:宋体;">校验。</span></span><span style="font-family: 宋体;font-size: 10.5pt;"><o:p></o:p></span></p><p><span style="font-family: 宋体;font-size: 10.5pt;"><span style="font-family:宋体;">  同</span><span style="font-family:Calibri;">ios</span><span style="font-family:宋体;">一样，在每次做完签名校验后，会把文件的签名信息加入到一个</span><span style="font-family:Calibri;">cache</span><span style="font-family:宋体;">中，如前所述，以后每次优先从</span><span style="font-family:Calibri;">cache</span><span style="font-family:宋体;">中获取签名信息，避免了解析文件获取签名信息的性能开销。</span></span><span style="font-family: 宋体;font-size: 10.5pt;"><o:p></o:p></span></p><p><span style="font-family: 宋体;font-size: 10.5pt;"><span style="font-family:宋体;">除了在内存维护一个</span><span style="font-family:Calibri;">cache</span><span style="font-family:宋体;">，还要给文件打个标签，利用了</span><span style="font-family:Calibri;">ntfs</span><span style="font-family:宋体;">的文件扩展属性，利用</span><span style="font-family:Calibri;">FsRtlSetKernelEaFile</span><span style="font-family:宋体;">函数将文件扩展属性设置为</span></span><span style="font-family: Calibri;font-size: 10.5pt;">“$Kernel.Purge.CIpCache”</span><span style="font-family: 宋体;font-size: 10.5pt;">。</span><span style="font-family: 宋体;font-size: 10.5pt;"><o:p></o:p></span></p><p><span style="font-family: Calibri;font-size: 10.5pt;">CiBuildEaCacheContents</span><span style="font-family: 宋体;font-size: 10.5pt;"><span style="font-family:宋体;">函数负责建立</span><span style="font-family:Calibri;">cache</span><span style="font-family:宋体;">结构体，对其参数进行跟踪分析：</span></span><span style="font-family: Calibri;font-size: 10.5pt;"><o:p></o:p></span></p><p><span style="font-family: Calibri;font-size: 10.5pt;">CI!CiBuildEaCacheContents<span style="font-family:宋体;">：</span></span><span style="font-family: Calibri;font-size: 10.5pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="http"><code><span class="code-snippet_outer"><span class="code-snippet__attribute">1</span>: kd&gt; dq r9 L8</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">fffffc0b`6767e8b0</span> <span class="code-snippet__string">ffff8686`3c08a600 0000800c`00000020</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">fffffc0b`6767e8c0</span> <span class="code-snippet__string">ffff8686`37f28d48 00008004`00000014</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">fffffc0b`6767e8d0</span> <span class="code-snippet__string">00000000`00000000 00000000`00000018</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">fffffc0b`6767e8e0</span> <span class="code-snippet__string">fffffc0b`6767e8f0 00000000`00000010</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">800c/8004是sha256/sha1的标志，微软采用了以下的标准：</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">md2</span> <span class="code-snippet__string">0x8001</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">md4</span> <span class="code-snippet__string">0x8002</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">md5</span> <span class="code-snippet__string">0x8003</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">sha1</span> <span class="code-snippet__string">0x8004</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">sha256</span> <span class="code-snippet__string">0x800c</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">sha384</span> <span class="code-snippet__string">0x800d</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">sha512</span> <span class="code-snippet__string">0x800e</span></span></code></pre></section><p><span style="font-family: 宋体;font-size: 10.5pt;"><span style="font-family:宋体;">  所以进一步猜测黄色部分对应的地址应该为保存</span><span style="font-family:Calibri;">hash</span><span style="font-family:宋体;">的地址，蓝色部分代表</span><span style="font-family:Calibri;">hash</span><span style="font-family:宋体;">值的大小，</span><span style="font-family:Calibri;">sha256</span><span style="font-family:宋体;">为</span><span style="font-family:Calibri;">0x20</span><span style="font-family:宋体;">字节，</span><span style="font-family:Calibri;">sha1</span><span style="font-family:宋体;">为</span><span style="font-family:Calibri;">0x14</span><span style="font-family:宋体;">字节，确实没错。由此笔者推导出的</span><span style="font-family:Calibri;">cache</span><span style="font-family:宋体;">结构体为：</span></span><span style="font-family: 宋体;font-size: 10.5pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">FileEaCache</span> {</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">FILE_FULL_EA_INFORMATION eaInfo;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">unkown_struct1</span> {</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">int</span> struct_length;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">short</span> a2;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">char</span> a3;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">char</span> a4;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">long</span> <span class="code-snippet__keyword">long</span> a5;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">long</span> a6;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">long</span> a7;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">} A1;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">unkown_struct2</span> {</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">char</span> struct_length;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">char</span> a1;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">int</span> hashType;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">char</span> hashSize;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">void</span> *hashValue;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">} A2[<span class="code-snippet__number">2</span>];</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">unkown_struct3</span> {</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">short</span> struct_length;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">int</span> hashType;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">char</span> hashSize;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">char</span> hashValue1[<span class="code-snippet__number">16</span>];</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">char</span> hashValue2[<span class="code-snippet__number">16</span>];</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">} A3[<span class="code-snippet__number">2</span>];</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family: 宋体;font-size: 10.5pt;">或者更合理的定义为：</span><span style="font-family: 宋体;font-size: 10.5pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">unkown_struct1</span> {</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">int</span> struct_length;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">short</span> a2;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">char</span> a3;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">char</span> a4;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">long</span> <span class="code-snippet__keyword">long</span> a5;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">long</span> a6;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">long</span> a7;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">};</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">unkown_struct2</span> {</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">char</span> struct_length;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">char</span> a1;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">int</span> hashType;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">char</span> hashSize;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">void</span> *hashValue;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">};</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">unkown_struct3</span> {</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">short</span> struct_length;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">int</span> hashType;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">char</span> hashSize;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">char</span> hashValue1[<span class="code-snippet__number">16</span>];</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">char</span> hashValue2[<span class="code-snippet__number">16</span>];</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">};</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">FileEaCache</span> {</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">FILE_FULL_EA_INFORMATION eaInfo;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">unkown_struct1</span> <span class="code-snippet__title">a1</span>;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">unkown_struct2</span> <span class="code-snippet__title">a2</span>, <span class="code-snippet__title">a3</span>;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">unkown_struct3</span> <span class="code-snippet__title">a4</span>, <span class="code-snippet__title">a5</span>;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">};</span></code></pre></section><p><span style="font-family: Calibri;font-size: 10.5pt;">    CiValidateImageHeader</span><span style="font-family: 宋体;font-size: 10.5pt;">函数中还有一个重要的函数</span><span style="font-family: Calibri;font-size: 10.5pt;">CipAllocateValidationContext</span><span style="font-family: 宋体;font-size: 10.5pt;"><span style="font-family:宋体;">，用于构造签名校验信息时统一用到的数据结构，这个结构体非常庞大，接近</span><span style="font-family:Calibri;">1k</span><span style="font-family:宋体;">字节。笔者只推导出了其中几个关键成员结构：</span></span><span style="font-family: 宋体;font-size: 10.5pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="diff"><code><span class="code-snippet_outer">Struct ValidateContext:</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x400 FileName</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x490 WIN_CERTIFATE</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x498 WIN_CERTIFATE_SIZE</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x578 FileNameInformation</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0x580 FileObject</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0xCf8 HashType</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__addition">+0xD40 Callbacks</span></span></code></pre></section><p><span style="font-family: 宋体;font-size: 10.5pt;"><span style="font-family:宋体;">  至于</span><span style="font-family:Calibri;">CipValidateFileHash</span><span style="font-family:宋体;">函数，太复杂了，大致操作就是验证签名信息本身是否正确，然后做</span><span style="font-family:Calibri;">hash</span><span style="font-family:宋体;">的对比。</span></span><span style="font-family: Calibri;font-size: 10.5pt;"><o:p></o:p></span></p><h4><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:14.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">2.3.2.2 Catalog</span><span style="font-family:黑体;">接口</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:14.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h4><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  前面提到文件签名信息除了可以保存在</span><span style="font-family:Calibri;">pe</span><span style="font-family:宋体;">文件内，还可以保存在独立的</span><span style="font-family:Calibri;">catalog</span><span style="font-family:宋体;">文件内，</span><span style="font-family:Calibri;">win11</span><span style="font-family:宋体;">版本路径为：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">C:\Windows\SystemApps\Microsoft.UI.Xaml.CBS_8wekyb3d8bbwe\AppxMetadata\CodeIntegrity.cat</span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p><span style="font-family: 宋体;font-size: 10.5pt;"><span style="font-family:宋体;">通过</span><span style="font-family:Calibri;">CiValidateImageHeader-&gt;CipFindFileHash-&gt;CI!CiVerifyFileHashInCatalogs</span><span style="font-family:宋体;">路径进行调用。</span></span><span style="font-family: 宋体;font-size: 10.5pt;"><o:p></o:p></span></p><p><span style="font-family: 宋体;font-size: 10.5pt;"><span style="font-family:宋体;">微软还提供了动态添加和删除</span><span style="font-family:Calibri;">catlog</span><span style="font-family:宋体;">文件的接口：</span><span style="font-family:Calibri;">CiAddDynamicCatalog</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">CiRemoveDynamicCatalogs</span><span style="font-family:宋体;">。</span></span><span style="font-family: 宋体;font-size: 10.5pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">__int64 __<span class="code-snippet__function">fastcall <span class="code-snippet__title">CiAddDynamicCatalog</span><span class="code-snippet__params">(WCHAR *a1, <span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">int</span> a2)</span></span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">RtlCopyUnicodeString(v8, &amp;SourceString);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> ( *(_WORD *)(*(_QWORD *)(v6 + <span class="code-snippet__number">16</span>) + <span class="code-snippet__number">2</span> * ((<span class="code-snippet__keyword">unsigned</span> __int64)v8-&gt;Length &gt;&gt; <span class="code-snippet__number">1</span>) - <span class="code-snippet__number">2</span>) != <span class="code-snippet__number">92</span> )</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">RtlAppendUnicodeStringToString(v8, &amp;Source);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">RtlAppendUnicodeStringToString(v8, &amp;stru_1C00259B0);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">for</span> ( i = (__int64 *)qword_1C0036880; i != &amp;qword_1C0036880; i = (__int64 *)*i )</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> ( (*(_DWORD *)(i - <span class="code-snippet__number">3</span>) &amp; <span class="code-snippet__number">0x10</span>) != <span class="code-snippet__number">0</span> &amp;&amp; RtlEqualUnicodeString(v8, (PCUNICODE_STRING)i - <span class="code-snippet__number">1</span>, <span class="code-snippet__number">1u</span>) )</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">v7 = <span class="code-snippet__number">0x40000000</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">goto</span> LABEL_33;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family: 宋体;font-size: 10.5pt;"><span style="font-family:宋体;">  可以看到</span><span style="font-family:Calibri;">catalog</span><span style="font-family:宋体;">文件名保存在一个链表中。</span></span><span style="font-family: 宋体;font-size: 10.5pt;"><o:p></o:p></span></p><h4><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:14.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">2.3.2.3 Pagefault</span><span style="font-family:黑体;">处理</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:14.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h4><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  同</span><span style="font-family:Calibri;">ios</span><span style="font-family:宋体;">一样，除了进程在建立时校验一次</span><span style="font-family:Calibri;">hash</span><span style="font-family:宋体;">外，在程序运行中，如果触发了页异常错误，也要对造成异常的页面做一次</span><span style="font-family:Calibri;">hash</span><span style="font-family:宋体;">值校验，包括当进程一个页面被换出到磁盘上，某个时刻又换回内存后，势必要进行一次</span><span style="font-family:Calibri;">hash</span><span style="font-family:宋体;">校验。当前</span><span style="font-family:Calibri;">win11</span><span style="font-family:宋体;">版本的页异常处理</span><span style="font-family:Calibri;">hash</span><span style="font-family:宋体;">值校验路径为：</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;">MmAccessFault-&gt;MiIssueHardFault-&gt;MiWaitForInPageComplete-&gt;MiValidateInPage-&gt;SeValidateImageData</span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">-&gt;CiValidateImageHeader</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  在页异常中处理</span><span style="font-family:Calibri;">hash</span><span style="font-family:宋体;">校验会非常消耗性能，微软的代码中虽然有了这些代码逻辑，但是如前面的章节所述，文件的签名信息内只包含了文件的</span><span style="font-family:Calibri;">hash</span><span style="font-family:宋体;">值，并没有包含文件的</span><span style="font-family:Calibri;">page hash</span><span style="font-family:宋体;">值。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:宋体;">  除了页异常，我们看到</span><span style="font-family:Calibri;">ios</span><span style="font-family:宋体;">在两个内存物理页进行拷贝的函数中也加入了</span><span style="font-family:Calibri;">hash</span><span style="font-family:宋体;">值校验，但是微软的工程师似乎忘记了这个路径。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><h4><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:14.0000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Arial;">2.3.2.4 </span><span style="font-family:黑体;">动态代码签名</span></span></strong><strong><span style="mso-spacerun:&#39;yes&#39;;font-family:黑体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:&#39;Times New Roman&#39;;mso-ansi-font-weight:bold;font-size:14.0000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></strong></h4><p><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><span style="font-family:Calibri;">   IOS</span><span style="font-family:宋体;">使用了</span><span style="font-family:Calibri;">Entitlement</span><span style="font-family:宋体;">机制，可以将一个</span><span style="font-family:Calibri;">app</span><span style="font-family:宋体;">标记为可以使用动态代码内存，比如浏览器进程需要使用</span><span style="font-family:Calibri;">jit</span><span style="font-family:宋体;">动态映射代码。</span><span style="font-family:Calibri;">Windows</span><span style="font-family:宋体;">的做法是内核提供接口，可以设置文件的某个扩展属性，把它标记为</span><span style="font-family:Calibri;">Trust</span><span style="font-family:宋体;">进程，可以使用动态代码，当签名校验时会判断是否为</span><span style="font-family:Calibri;">trust</span><span style="font-family:宋体;">进程，就可以绕过签名校验。</span></span><span style="mso-spacerun:&#39;yes&#39;;font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:&#39;Times New Roman&#39;;font-size:10.5000pt;mso-font-kerning:1.0000pt;"><o:p></o:p></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">__int64 __<span class="code-snippet__function">fastcall <span class="code-snippet__title">CiSetDynamicCodeTrustClaim</span><span class="code-snippet__params">(__int64 a1, __int64 a2)</span></span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">Pool2 = ExAllocatePool2(<span class="code-snippet__number">258</span>i64, <span class="code-snippet__number">45</span>i64, <span class="code-snippet__number">0x63734943</span>i64);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">v6 = (<span class="code-snippet__keyword">void</span> *)Pool2;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> ( Pool2 )</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">*(_DWORD *)Pool2 = <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">*(_WORD *)(Pool2 + <span class="code-snippet__number">4</span>) = <span class="code-snippet__number">6144</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">*(_WORD *)(Pool2 + <span class="code-snippet__number">6</span>) = <span class="code-snippet__number">12</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__built_in">strcpy</span>((<span class="code-snippet__keyword">char</span> *)(Pool2 + <span class="code-snippet__number">8</span>), <span class="code-snippet__string">&#34;$Kernel.Purge.TrustClaim&#34;</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">*(<span class="code-snippet__keyword">void</span> **)(Pool2 + <span class="code-snippet__number">33</span>) = Object[<span class="code-snippet__number">0</span>];</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">*(_DWORD *)(Pool2 + <span class="code-snippet__number">41</span>) = <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">v4 = FsRtlSetKernelEaFile(v3, Pool2, <span class="code-snippet__number">45</span>i64);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">ExFreePoolWithTag(v6, <span class="code-snippet__number">0x63734943</span>u);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">__int64 __<span class="code-snippet__function">fastcall <span class="code-snippet__title">CipQueryDynamicCodeTrustClaim</span><span class="code-snippet__params">(PFILE_OBJECT a1, _QWORD *a2)</span></span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">v6 = FsRtlQueryKernelEaFile(a1, Pool2 + <span class="code-snippet__number">32</span>, <span class="code-snippet__number">48</span>i64, <span class="code-snippet__number">0</span>i64, Pool2, <span class="code-snippet__number">32</span>, <span class="code-snippet__number">0</span>i64, <span class="code-snippet__number">0</span>, &amp;v12);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> ( v6 &gt;= <span class="code-snippet__number">0</span> )</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">v8 = *(<span class="code-snippet__keyword">unsigned</span> __int8 *)(v7 + <span class="code-snippet__number">5</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">String1.Buffer = (PCHAR)(v7 + <span class="code-snippet__number">8</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">String1.Length = *(<span class="code-snippet__keyword">unsigned</span> __int8 *)(v7 + <span class="code-snippet__number">5</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">String1.MaximumLength = *(<span class="code-snippet__keyword">unsigned</span> __int8 *)(v7 + <span class="code-snippet__number">5</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> ( RtlEqualString(&amp;String1, &amp;g_CiTrustClaimEaName, <span class="code-snippet__number">1u</span>) )</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style="display: none;"><mp-style-type data-value="3"></mp-style-type></p>



<p><a href="2247483791">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=50106a6f&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg4NjU1NDU4MA%3D%3D%26mid%3D2247483791%26idx%3D1%26sn%3D1f066b3ced7063dace9424f5ab782b63%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Wed, 28 Feb 2024 15:32:00 +0800</pubDate>
    </item>
    <item>
      <title>IOS PAC实现详解</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg4NjU1NDU4MA==&amp;mid=2247483774&amp;idx=1&amp;sn=3f1d304fe16cb29afe98ace4173bb658</link>
      <description>IOS PAC实现详解</description>
      <content:encoded><![CDATA[<p>
原创 <span>wzt</span> <span>2021-12-06 11:09</span> <span style="display: inline-block;"></span>
</p>

<p>IOS PAC实现详解</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=73e8ca16&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F4iaJia7Cvd3PAibfAyY2guUxGpKsIdcWUycPr2QDvJ9xfSyOnrEbKHtWqS9zS5ksLjzicYDGu2AI7cnpC71levgJzg%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<p><span style="font-family: 宋体;font-size: 29px;">1. </span><strong style="font-size: 16px;"><span style="font-family:宋体;font-size:29px;">内核<span style="font-family:Calibri;">pac key</span>初始化</span></strong><br/></p><h1><strong><span style="font-family:宋体;font-size:29px;"><span style="font-family:宋体;"></span></span></strong></h1><p><span style="font-family:Calibri;font-size:14px;">common_start</span></p><p><span style="font-family:Calibri;font-size:14px;">mrs     </span><span style="font-family:Calibri;font-size:14px;">x0, S3_4_C15_C0_4</span></p><p><span style="font-family:Calibri;font-size:14px;">and     </span><span style="font-family:Calibri;font-size:14px;">x1, x0, #0x2</span></p><p><span style="font-family:Calibri;font-size:14px;">cbz     </span><span style="font-family:Calibri;font-size:14px;">x1, 0xfffffff0081384d0</span></p><p><span style="font-family:Calibri;font-size:14px;">orr     </span><span style="font-family:Calibri;font-size:14px;">x0, x0, #0x1</span></p><p><span style="font-family:Calibri;font-size:14px;">orr     </span><span style="font-family:Calibri;font-size:14px;">x0, x0, #0x4</span></p><p><span style="font-family:Calibri;font-size:14px;">msr     </span><span style="font-family:Calibri;font-size:14px;">S3_4_C15_C0_4, x0</span></p><p><span style="font-family:Calibri;font-size:14px;">Isb</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">首先探测下</span><span style="font-family:Calibri;font-size:14px;">S3_4_C15_C0_4</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">寄存器的第</span><span style="font-family:Calibri;">2</span><span style="font-family:宋体;">个</span><span style="font-family:Calibri;">bit</span><span style="font-family:宋体;">是否为</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">， 如果为</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">， 则一直等待下去，否则把其第</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">个和第</span><span style="font-family:Calibri;">3</span><span style="font-family:宋体;">个比特位置</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">，结合后面对</span><span style="font-family:Calibri;">_ml_set_kernelkey_enabled</span><span style="font-family:宋体;">的分析，可以推测出</span></span><span style="font-family:Calibri;font-size:14px;">S3_4_C15_C0_4</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">寄存器是苹果公司为增强</span><span style="font-family:Calibri;">pac</span><span style="font-family:宋体;">而加入的控制寄存器。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X0, =</span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">0xFEEDFACEFEEDFACF</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #0, c2, c1, #2, X0 ; APIBKeyLo_EL1</span></p><p><span style="font-family:Calibri;font-size:14px;">ADD             X0, X0, #1</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #0, c2, c1, #3, X0 ; APIBKeyHi_EL1</span></p><p><span style="font-family:Calibri;font-size:14px;">ADD             X0, X0, #1</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #0, c2, c2, #2, X0 ; APDBKeyLo_EL1</span></p><p><span style="font-family:Calibri;font-size:14px;">ADD             X0, X0, #1</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #0, c2, c2, #3, X0 ; APDBKeyHi_EL1</span></p><p><span style="font-family:Calibri;font-size:14px;">ADD             X0, X0, #1</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #4, c15, c1, #0, X0</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">; ???</span></span></p><p><span style="font-family:Calibri;font-size:14px;">ADD             X0, X0, #1</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #4, c15, c1, #1, X0</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">; ???</span></span></p><p><span style="font-family:Calibri;font-size:14px;">ADD             X0, X0, #1</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #0, c2, c1, #0, X0 ; APIAKeyLo_EL1</span></p><p><span style="font-family:Calibri;font-size:14px;">ADD             X0, X0, #1</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #0, c2, c1, #1, X0 ; APIAKeyHi_EL1</span></p><p><span style="font-family:Calibri;font-size:14px;">ADD             X0, X0, #1</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #0, c2, c2, #0, X0 ; APDAKeyLo_EL1</span></p><p><span style="font-family:Calibri;font-size:14px;">ADD             X0, X0, #1</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #0, c2, c2, #1, X0 ; APDAKeyHi_EL1</span></p><p><span style="font-family:Calibri;font-size:14px;">ADD             X0, X0, #1</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #0, c2, c3, #0, X0 ; APGAKeyLo_EL1</span></p><p><span style="font-family:Calibri;font-size:14px;">ADD             X0, X0, #1</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #0, c2, c3, #1, X0 ; APGAKeyHi_EL1</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">Iphone12</span><span style="font-family:宋体;">使用固定值</span></span><span style="font-family:Calibri;font-size:14px;">0xFEEDFACEFEEDFACF</span><span style="font-family:宋体;font-size:14px;">依次初始化</span><span style="font-family:Calibri;font-size:14px;">API</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">A</span></span><span style="font-family:Calibri;font-size:14px;">Key_EL1</span><span style="font-family:宋体;font-size:14px;">、</span><span style="font-family:Calibri;font-size:14px;">API</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">B</span></span><span style="font-family:Calibri;font-size:14px;">Key_EL1</span><span style="font-family:宋体;font-size:14px;">、</span><span style="font-family:Calibri;font-size:14px;">AP</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">DA</span></span><span style="font-family:Calibri;font-size:14px;">Key_EL1</span><span style="font-family:宋体;font-size:14px;">、</span><span style="font-family:Calibri;font-size:14px;">AP</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">DB</span></span><span style="font-family:Calibri;font-size:14px;">Key_EL1</span><span style="font-family:宋体;font-size:14px;">、</span><span style="font-family:Calibri;font-size:14px;">AP</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">GA</span></span><span style="font-family:Calibri;font-size:14px;">Key_EL1</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">寄存器。高版本的</span><span style="font-family:Calibri;">Iphone</span><span style="font-family:宋体;">内核是否也使用固定值有待确认。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">MOVK            X0, #0,LSL#48</span></p><p><span style="font-family:Calibri;font-size:14px;">MOVK            X0, #0,LSL#32</span></p><p><span style="font-family:Calibri;font-size:14px;">MOVK            X0, #0x3454,LSL#16</span></p><p><span style="font-family:Calibri;font-size:14px;">MOVK            X0, #0x593D ; 0x3454593d</span></p><p><span style="font-family:Calibri;font-size:14px;">ORR             X0, X0, #0x40000000 ; 0x7454593d</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #0, c1, c0, #0, X0 ; SCTLR_EL1</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">很奇怪这里</span><span style="font-family:Calibri;">sctlr_el1</span><span style="font-family:宋体;">只设置了</span><span style="font-family:Calibri;">EnIB</span><span style="font-family:宋体;">位（笔者翻遍了代码，也没发现对</span><span style="font-family:Calibri;">sctlr_el1</span><span style="font-family:宋体;">其他</span><span style="font-family:Calibri;">pac</span><span style="font-family:宋体;">比特位的使用）。</span></span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><h1><span style="font-family:宋体;font-size:29px;">2. </span><strong><span style="font-family:宋体;font-size:29px;"><span style="font-family:宋体;">用户进程</span><span style="font-family:Calibri;">pac key</span><span style="font-family:宋体;">初始化</span></span></strong></h1><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">通过</span><span style="font-family:Calibri;">execve</span><span style="font-family:宋体;">执行一个</span><span style="font-family:Calibri;">binary</span><span style="font-family:宋体;">时，</span><span style="font-family:Calibri;">XNU</span><span style="font-family:宋体;">内核会进行新进程</span><span style="font-family:Calibri;">pac key</span><span style="font-family:宋体;">的初始化，</span><span style="font-family:Calibri;">XNU</span><span style="font-family:宋体;">将每个进程的</span><span style="font-family:Calibri;">pac key</span><span style="font-family:宋体;">保存在一个叫做</span><span style="font-family:Calibri;">shared region</span><span style="font-family:宋体;">的进程内存区域，这个区域可以被其他进程共享代码和数据，用来加快进程的启动速度，通常情况下一个进程只有一个</span><span style="font-family:Calibri;">shared region</span><span style="font-family:宋体;">区域，但是在支持</span><span style="font-family:Calibri;">pac</span><span style="font-family:宋体;">的情况下，</span><span style="font-family:Calibri;">shared region</span><span style="font-family:宋体;">根据不同的</span><span style="font-family:Calibri;">shared_region_id</span><span style="font-family:宋体;">会有不同的</span><span style="font-family:Calibri;">shared region</span><span style="font-family:宋体;">区域，通过一个队列</span></span><span style="font-family:Calibri;font-size:14px;">_shared_region_jop_key_queue</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">链接起来，每个节点是一个</span><span style="font-family:Calibri;">struct shared_region_jop_key_map</span><span style="font-family:宋体;">类型的结构体，</span><span style="font-family:Calibri;">xnu source code</span><span style="font-family:宋体;">有如下定义：</span></span></p><p><span style="font-family:Calibri;font-size:14px;">typedef struct shared_region_jop_key_map {</span></p><p><span style="font-family:Calibri;font-size:14px;">        queue_chain_t  srk_queue;</span></p><p><span style="font-family:Calibri;font-size:14px;">        char           *srk_shared_region_id;</span></p><p><span style="font-family:Calibri;font-size:14px;">        uint64_t       srk_jop_key;</span></p><p><span style="font-family:Calibri;font-size:14px;">        os_refcnt_t    srk_ref_count;         /* count of tasks active with this shared_region_id */</span></p><p><span style="font-family:Calibri;font-size:14px;">} *shared_region_jop_key_map_t;</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">成员</span><span style="font-family:Calibri;font-size:14px;">srk_jop_key</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">保存的是这个</span><span style="font-family:Calibri;">region</span><span style="font-family:宋体;">所使用的</span><span style="font-family:Calibri;">pac key</span><span style="font-family:宋体;">。下面我们来看下</span><span style="font-family:Calibri;">pac key</span><span style="font-family:宋体;">是如何被初始化的。</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">/*</span></span></p><p><span style="font-family:Calibri;font-size:14px;">void</span></p><p><span style="font-family:Calibri;font-size:14px;">shared_region_key_alloc(char *shared_region_id, bool inherit, uint64_t inherited_key)</span></p><p><span style="font-family:宋体;font-size:14px;"> <span style="font-family:Calibri;">*/</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">exec_mach_imgact</span></span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">-&gt;_shared_region_key_alloc</span></span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X8, [X24] ; _shared_region_jop_key_queue</span></p><p><span style="font-family:Calibri;font-size:14px;">CMP             X8, X24</span></p><p><span style="font-family:Calibri;font-size:14px;">B. </span><span style="font-family:Calibri;font-size:14px;">EQ            loc_FFFFFFF007B33338 ;</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">遍历</span><span style="font-family:Calibri;font-size:14px;">_shared_region_jop_key_queue</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">，如果队列为空，跳转到后面去申请一个新的</span><span style="font-family:Calibri;">shared_region</span><span style="font-family:宋体;">节点。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X9, X8</span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X10, [X9,#0x10]</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X11, X22</span></p><p><span style="font-family:Calibri;font-size:14px;">LDRB            W12, [X10]</span></p><p><span style="font-family:Calibri;font-size:14px;">LDRB            W13, [X11]</span></p><p><span style="font-family:Calibri;font-size:14px;">CMP             W12, W13</span></p><p><span style="font-family:Calibri;font-size:14px;">B.NE            loc_FFFFFFF007B3332C</span></p><p><span style="font-family:Calibri;font-size:14px;">ADD             X11, X11, #1</span></p><p><span style="font-family:Calibri;font-size:14px;">ADD             X10, X10, #1</span></p><p><span style="font-family:Calibri;font-size:14px;">CBNZ            W12, loc_FFFFFFF007B3330C</span></p><p><span style="font-family:Calibri;font-size:14px;">B               </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">loc_FFFFFFF007B33450</span><span style="font-family:Calibri;font-size:14px;"> ; srk_ref_count</span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X9, [X9]</span></p><p><span style="font-family:Calibri;font-size:14px;">CMP             X9, X24</span></p><p style="margin-left:0;text-indent:0;"><span style="font-family:Calibri;font-size:14px;">C. </span><span style="font-family:Calibri;font-size:14px;">NE            loc_FFFFFFF007B33304</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">循环遍历每个</span><span style="font-family:Calibri;">shared_region</span><span style="font-family:宋体;">节点，如果节点名与第一个参数相同，证明存在一个要匹配的节点。</span></span></p><p style="text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">__TEXT_EXEC:__text:FFFFFFF007B33450</span></span></p><p style="text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">E ADD             X0, X9, #0x20 ; &#39; &#39; ; srk_ref_count</span></span></p><p style="text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             W8, #1__TEXT_EXEC:__text:FFFFFFF007B33458                 LDADD           W8, W8, [X0] ; srk_ref_count++</span></span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">将引用计数</span><span style="font-family:Calibri;">srk_ref_count</span><span style="font-family:宋体;">加</span><span style="font-family:Calibri;">1.</span></span></p><p style="text-align:left;"><span style="font-family: 宋体;font-size: 14px;"><span style="font-family:Calibri;">CBZ             W8, loc_FFFFFFF007B33554</span></span></p><p style="text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             W10, #0xFFFFFFF</span></span></p><p style="text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">CMP             W8, W10</span></span></p><p style="text-align:left;"><span style="font-family:宋体;font-size:14px;">B. </span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">CS            loc_FFFFFFF007B33558</span></span></p><p style="margin-left:28px;text-align:left;"><span style="font-family:宋体;font-size:14px;">判断引用计数是否溢出</span></p><p style="text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             X22, X21 ; x21 == 0</span></span></p><p style="text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             X21, X9</span></span></p><p style="text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">CBZ             W20, loc_FFFFFFF007B33488 ; inherit == 0</span></span></p><p style="text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">LDR             X8, [X21,#0x18] ; inherit == 1 -&gt; srk_jop_key</span></span></p><p style="text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">LDR             X9, [SP,#0x70+var_60]</span></span></p><p style="text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">CMP             X8, X9  ; arg3: inherited_key</span></span></p><p style="margin-left:0;text-indent:0;text-align:left;"><span style="font-family:宋体;font-size:14px;">C. </span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">NE            loc_FFFFFFF007B3356C</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">如果第二个参数</span><span style="font-family:Calibri;">inherit</span><span style="font-family:宋体;">为</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">，并且此</span><span style="font-family:Calibri;">shared_region</span><span style="font-family:宋体;">保存的</span><span style="font-family:Calibri;">pac key</span><span style="font-family:宋体;">与第三个参数不相同，则</span><span style="font-family:Calibri;">panic</span><span style="font-family:宋体;">，否则直接返回，不需要更新</span><span style="font-family:Calibri;">pac key</span><span style="font-family:宋体;">。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">下面看下队列如果为空，或者没有找到要匹配到的</span><span style="font-family:Calibri;">shared_region_id</span><span style="font-family:宋体;">的后续处理流程。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">ADRL            X0, _KHEAP_DEFAULT</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W1, #0x28 ; &#39;(&#39;</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W2, #0</span></p><p><span style="font-family:Calibri;font-size:14px;">ADRL            X3, _shared_region_key_alloc.site</span></p><p><span style="font-family:Calibri;font-size:14px;">BL              _kalloc_ext</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">分配一个新的</span><span style="font-family:Calibri;font-size:14px;">struct shared_region_jop_key_map</span><span style="font-family:宋体;font-size:14px;">结构体</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X21, X0 ; new struct shared_region_jop_key_map</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X0, X22 ; __s</span></p><p><span style="font-family:Calibri;font-size:14px;">BL              _strlen ; shared_region_id</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">计算参数</span><span style="font-family:Calibri;">1</span></span><span style="font-family:Calibri;font-size:14px;">shared_region_id</span><span style="font-family:宋体;font-size:14px;">的长度</span></p><p><span style="font-family:Calibri;font-size:14px;">ADD             W28, W0, #1</span></p><p><span style="font-family:Calibri;font-size:14px;">ADRL            X0, _KHEAP_DATA_BUFFERS</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X1, X28</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W2, #0</span></p><p><span style="font-family:Calibri;font-size:14px;">ADRL            X3, _shared_region_key_alloc.site.3</span></p><p><span style="font-family:Calibri;font-size:14px;">BL              _kalloc_ext ; alloc shared_region_id buffer</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">分配</span><span style="font-family:Calibri;font-size:14px;">shared_region_id</span><span style="font-family:宋体;font-size:14px;">内存</span></p><p><span style="font-family:Calibri;font-size:14px;">STR             X0, [X21,#0x10] ; set srk_shared_region_id</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">保存</span><span style="font-family:Calibri;font-size:14px;">shared_region_id</span><span style="font-family:宋体;font-size:14px;">到</span><span style="font-family:Calibri;font-size:14px;">struct shared_region_jop_key_map</span><span style="font-family:宋体;font-size:14px;">对应成员。</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X1, X22 ; __source</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X2, X28 ; __size</span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X23, [SP,#0x70+var_60]</span></p><p><span style="font-family:Calibri;font-size:14px;">BL              _strlcpy ; strlcpy(srk_shared_region_id, shared_region_id, size);</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">拷贝</span><span style="font-family:Calibri;">shared_region_id</span><span style="font-family:宋体;">。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W8, #1</span></p><p><span style="font-family:Calibri;font-size:14px;">STR             W8, [X21,#0x20] ; srk_ref_count = 1</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">引用计数</span><span style="font-family:Calibri;font-size:14px;">srk_ref_count</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">初始化为</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">ADRP            X8, #_diversify_user_jop@PAGE</span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             W9, [X8,#_diversify_user_jop@PAGEOFF]</span></p><p><span style="font-family:Calibri;font-size:14px;">CMP             W9, #0</span></p><p><span style="font-family:Calibri;font-size:14px;">CSET            W8, NE</span></p><p><span style="font-family:Calibri;font-size:14px;">TST             W8, W20 ; arg2: inherit</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X8, #0xFEEDFACEFEEDFAD5</span></p><p><span style="font-family:Calibri;font-size:14px;">CSEL            X8, X23, X8, NE ; x23: arg3 inherit</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">如果</span><span style="font-family:Calibri;font-size:14px;">diversify_user_jop</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">为</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">并且第</span><span style="font-family:Calibri;">2</span><span style="font-family:宋体;">个参数</span></span><span style="font-family:Calibri;font-size:14px;">inherit</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">也为</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">，</span><span style="font-family:Calibri;">x8</span><span style="font-family:宋体;">被设置为第三个参数</span></span><span style="font-family:Calibri;font-size:14px;">inherit</span><span style="font-family:宋体;font-size:14px;">，否则设置为</span><span style="font-family:Calibri;font-size:14px;">0xFEEDFACEFEEDFAD5</span><span style="font-family:宋体;font-size:14px;">。</span></p><p><span style="font-family:Calibri;font-size:14px;">ADRL            X24, _shared_region_jop_key_queue</span></p><p><span style="font-family:Calibri;font-size:14px;">CBZ             W9, loc_FFFFFFF007B33444</span></p><p><span style="font-family:Calibri;font-size:14px;">TBNZ            W20, #0, loc_FFFFFFF007B33444</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X0, X22 ; __s</span></p><p><span style="font-family:Calibri;font-size:14px;">BL              _strlen</span></p><p><span style="font-family:Calibri;font-size:14px;">CBZ             X0, loc_FFFFFFF007B33434 ; strlen(shared_region_id) == 0</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">如果</span><span style="font-family:Calibri;font-size:14px;">shared_region_id</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">长度为</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">， </span><span style="font-family:Calibri;">x8</span><span style="font-family:宋体;">设置为</span></span><span style="font-family:Calibri;font-size:14px;">0xFEEDFACEFEEDFA</span><span style="font-family:Calibri;font-size:14px;background:rgb(0,255,0);background:rgb(0,255,0);">D5</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">。我们看到用户进程的</span><span style="font-family:Calibri;">pac key</span><span style="font-family:宋体;">居然和内核的</span><span style="font-family:Calibri;">pac key</span></span><span style="font-family:Calibri;font-size:14px;">0xFEEDFACEFEEDFA</span><span style="font-family:Calibri;font-size:14px;background:rgb(0,255,0);background:rgb(0,255,0);">CF</span><span style="font-family:宋体;font-size:14px;">值很接近！</span></p><p><span style="font-family:Calibri;font-size:14px;">__TEXT_EXEC:__text:FFFFFFF007B333FC</span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X8, [X19]</span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X0, [X26,#_prng_ctx@PAGEOFF]</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">BLRAA</span><span style="font-family:Calibri;font-size:14px;">           X8, X28</span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X8, [X19,#(qword_FFFFFFF0076E7760 - 0xFFFFFFF0076E7758)]</span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X0, [X26,#_prng_ctx@PAGEOFF]</span></p><p><span style="font-family:Calibri;font-size:14px;">MRS             X9, #0, c13, c0, #4 ; TPIDR_EL1</span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X9, [X9,#0x4F8]</span></p><p><span style="font-family:Calibri;font-size:14px;">LDRH            W1, [X9]</span></p><p><span style="font-family:Calibri;font-size:14px;">ADD             X3, SP, #0x70+var_58</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W2, #8</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">BLRAA</span><span style="font-family:Calibri;font-size:14px;">           X8, X25</span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X8, [SP,#0x70+var_58]</span></p><p><span style="font-family:Calibri;font-size:14px;">CBZ             X8, loc_FFFFFFF007B333FC</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">获取一个随机数，赋值给</span><span style="font-family:Calibri;">x8</span><span style="font-family:宋体;">。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">STR             X8, [X21,#0x18]</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">X8</span><span style="font-family:宋体;">为要保存的</span><span style="font-family:Calibri;">pac key</span><span style="font-family:宋体;">值。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">总结以下，一个进程可以继承父进程的</span><span style="font-family:Calibri;">pac key</span><span style="font-family:宋体;">，可以是个随机值，还可以是固定值</span></span><span style="font-family:Calibri;font-size:14px;">0xFEEDFACEFEEDFA</span><span style="font-family:Calibri;font-size:14px;">D5</span><span style="font-family:宋体;font-size:14px;">。</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">这里还存在另一个安全问题，虽然把生成随机数的两个函数指针都使用</span><span style="font-family:Calibri;">pac</span><span style="font-family:宋体;">签名过，但是</span><span style="font-family:Calibri;">pac</span><span style="font-family:宋体;">计算过程中使用的</span><span style="font-family:Calibri;">context</span><span style="font-family:宋体;">值居然是个固定的</span><span style="font-family:Calibri;">4</span><span style="font-family:宋体;">个字节值：</span><span style="font-family:Calibri;">0x2ABE</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">0x9BF6</span><span style="font-family:宋体;">。这会弱化随机数生成函数的安全性。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h1><span style="font-family:宋体;font-size:29px;">3. </span><strong><span style="font-family:宋体;font-size:29px;"><span style="font-family:宋体;">进程之间切换</span><span style="font-family:Calibri;">pac</span></span></strong></h1><p style="text-indent:28px;text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">由于每个进程的</span><span style="font-family:Calibri;">pac key</span><span style="font-family:宋体;">可能不同，所以在进程切换的时候，也需要切换</span><span style="font-family:Calibri;">pac key</span><span style="font-family:宋体;">。</span></span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">_Switch_context</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">STR             XZR, [X3,#0x78] ; </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">SS64_KERNEL_PC</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOV             W4, #0x100004 ; </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">PSR64_KERNEL_POISON</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">STR             W4, [X3,#0x80] ; </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">SS64_KERNEL_CPSR</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">STP             X0, X1, [SP,#var_10]!</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">STP             X2, X3, [SP,#0x10+var_20]!</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">STP             X4, X5, [SP,#0x20+var_30]!</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOV             X0, X3</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOV             X1, #0</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOV             W2, W4</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOV             X3, X30</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOV             X4, X16</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOV             X5, X17</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">BL              _ml_sign_kernel_thread_state ; </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">compute old thread pac code.</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">在进程切换前，首先计算处当前进程的</span><span style="font-family:Calibri;">thread state pac</span><span style="font-family:宋体;">值。</span><span style="font-family:Calibri;">linux</span><span style="font-family:宋体;">内核也提供了</span><span style="font-family:Calibri;">pac</span><span style="font-family:宋体;">服务，但是没有对</span><span style="font-family:Calibri;">thread</span><span style="font-family:宋体;">状态做校验。</span></span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">__TEXT_EXEC:__text:FFFFFFF008139A8C _ml_sign_kernel_thread_state            ; CODE PACGA           X1, X1, X0</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">AND             X2, X2, #0xFFFFFFFFDFFFFFFF</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">PACGA           X1, X2, X1</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">PACGA           X1, X3, X1</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">PACGA           X1, X4, X1</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">PACGA           X1, X5, X1</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">STR             X1, [X0,#0x88] ; struct arm_kernel_saved_state-&gt;jophash</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">RET</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">Pacga</span><span style="font-family:宋体;">指令用于计算大块的内存区域，可以看到</span><span style="font-family:Calibri;">XNU</span><span style="font-family:宋体;">使用</span><span style="font-family:Calibri;">pacga</span><span style="font-family:宋体;">指令依次对</span><span style="font-family:Calibri;">x0: The ARM context pointer</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">x1: PC value to sign</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">x2: CPSR value to sign</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">x3: LR to sign</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">x16</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">x17</span><span style="font-family:宋体;">做计算生成</span><span style="font-family:Calibri;">pac</span><span style="font-family:宋体;">。</span></span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">X0</span><span style="font-family:宋体;">是一个</span><span style="font-family:Calibri;">struct arm_kernel_save_state</span><span style="font-family:宋体;">的数据结构：</span></span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;"> struct arm_kernel_saved_state {</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:Calibri;font-size:14px;">uint64_t x[12];     /* General purpose registers x16-x28 */</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:Calibri;font-size:14px;">uint64_t fp;        /* Frame pointer x29 */</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:Calibri;font-size:14px;">uint64_t lr;        /* Link register x30 */</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:Calibri;font-size:14px;">uint64_t sp;        /* Stack pointer x31 */</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:Calibri;font-size:14px;">uint64_t pc;        /* Program counter */</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:Calibri;font-size:14px;">uint32_t cpsr;      /* Current program status register */</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:Calibri;font-size:14px;">uint64_t jophash;</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">} __attribute__((aligned(16)));</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">在生成当前进程的</span><span style="font-family:Calibri;">thread state pac</span><span style="font-family:宋体;">后，开始校验下要切换的进程</span><span style="font-family:Calibri;">thread state</span><span style="font-family:宋体;">状态，如果校验不过，证明要切换的进程状态被篡改过，系统直接</span><span style="font-family:Calibri;">panic</span><span style="font-family:宋体;">。</span></span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:Calibri;font-size:14px;">LDR             X3, [X2,#0x498] ; </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">new TH_KSTACKPTR</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOV             X20, X0</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOV             X21, X1</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOV             X22, X2</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOV             X0, X3</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:Calibri;font-size:14px;">LDR             W2, [X0,#0x80] ; </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">new SS64_KERNEL_CPSR</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:Calibri;font-size:14px;">DMB             LD</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:Calibri;font-size:14px;">LDR             X1, [X0,#0x78] ; </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">new SS64_KERNEL_PC</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:Calibri;font-size:14px;">LDP             X16, X17, [X0]</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOV             X25, X3</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOV             X26, X4</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOV             X27, X5</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOV             X23, X1</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOV             X24, X2</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:Calibri;font-size:14px;">LDR             X3, [X0,#0x68]</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOV             X4, X16</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOV             X5, X17</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:Calibri;font-size:14px;">BL              _ml_check_kernel_signed_state ; </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">check new thread pac code.</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">__TEXT_EXEC:__text:FFFFFFF008139AEC _ml_check_kernel_signed_state           ; CODE PACGA           X1, X1, X0</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">AND             X2, X2, #0xFFFFFFFFDFFFFFFF</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">PACGA           X1, X2, X1</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">PACGA           X1, X3, X1</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">PACGA           X1, X4, X1</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">PACGA           X1, X5, X1</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">LDR             X2, [X0,#0x88]</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:宋体;font-size:14px;">从</span><span style="font-family:Calibri;font-size:14px;">struct arm_kernel_saved_state</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">结构体提取</span><span style="font-family:Calibri;">pac code</span><span style="font-family:宋体;">。</span></span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">CMP             X1, X2</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">B.NE            loc_FFFFFFF008139B14</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">RET</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:宋体;font-size:14px;">相同返回上层函数。</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">__TEXT_EXEC:__text:FFFFFFF008139B14 ;</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">PACIBSP</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">STP             X29, X30, [SP,#var_10]!</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOV             X29, SP</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">BL              _panic</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">不相同则</span><span style="font-family:Calibri;">panic</span><span style="font-family:宋体;">系统。</span></span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">LDR             X5, [X2,#0x4F8]</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOV             W6, #0</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">LDR             X3, [X2,#0x508]</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">LDR             X4, [X5,#0x200]</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">CMP             X3, X4</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">B.EQ            loc_FFFFFFF008138B48</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">STR             X3, [X5,#0x200]</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MSR             #0, c2, c1, #2, X3 ; </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">APIBKeyLo_EL1</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">ADD             X3, X3, #1</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MSR             #0, c2, c1, #3, X3 ;</span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"> APIBKeyHi_EL1</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">ADD             X3, X3, #1</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MSR             #0, c2, c2, #2, X3 ;</span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"> APDBKeyLo_EL1</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">ADD             X3, X3, #1</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MSR             #0, c2, c2, #3, X3 ; </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">APDBKeyHi_EL1</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">加载新进程的</span><span style="font-family:Calibri;">pac key</span><span style="font-family:宋体;">到对应的系统寄存器。</span></span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h1><strong><span style="font-family:宋体;font-size:29px;"><span style="font-family:Calibri;">4 </span><span style="font-family:宋体;">内核</span><span style="font-family:Calibri;">pac</span><span style="font-family:宋体;">与用户进程</span><span style="font-family:Calibri;">pac</span><span style="font-family:宋体;">切换</span></span></strong></h1><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">4.1 </span><span style="font-family:黑体;">进入内核</span></span></strong></h2><p style="text-indent:28px;text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">进程每次通过系统调用进入内核或者发生错误进入内核异常处理流程时，需要把进程的</span><span style="font-family:Calibri;">pac key</span><span style="font-family:宋体;">切换为内核的</span><span style="font-family:Calibri;">pac key</span><span style="font-family:宋体;">。</span></span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">__TEXT_EXEC:__text:FFFFFFF008131410 fleh_dispatch64</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOVK            X2, #0xFEED,LSL#48</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOVK            X2, #0xFACE,LSL#32</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOVK            X2, #0xFEED,LSL#16</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOVK            X2, #0xFAD5 ; </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">0xFEEDFACEFEEDFAD5</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MRS             X3, #0, c13, c0, #4 ; TPIDR_EL1</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">LDR             X3, [X3,#0x4F8]</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">LDR             X4, [X3,#0x208]</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">CMP             X2, X4</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">B.EQ            loc_FFFFFFF0081314F0</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MSR             #0, c2, c1, #0, X2 ; APIAKeyLo_EL1</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">ADD             X4, X2, #1</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MSR             #0, c2, c1, #1, X4 ; APIAKeyHi_EL1</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">ADD             X4, X4, #1</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MSR             #0, c2, c2, #0, X4 ; APDAKeyLo_EL1</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">ADD             X4, X4, #1</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MSR             #0, c2, c2, #1, X4 ; APDAKeyHi_EL1</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">STR             X2, [X3,#0x208]</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">在进入内核时，首先要更新</span><span style="font-family:Calibri;">APIAKey_EL1</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">APDAKey_EL1</span><span style="font-family:宋体;">为固定值</span></span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">0xFEEDFACEFEEDFAD5</span><span style="font-family:宋体;font-size:14px;">极其增值。</span></p><p style="text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             X21, X1</span></span></p><p style="text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             X20, X30</span></span></p><p style="text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             X1, X22</span></span></p><p style="text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             W2, W23</span></span></p><p style="text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             X3, X20</span></span></p><p style="text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             X4, X16</span></span></p><p style="text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             X5, X17</span></span></p><p style="text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">BL              _ml_sign_thread_state</span></span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">更新完</span><span style="font-family:Calibri;">pac key</span><span style="font-family:宋体;">值，马上对当前进程的</span><span style="font-family:Calibri;">thread state</span><span style="font-family:宋体;">进行签名。</span></span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">4.2 </span><span style="font-family:黑体;">退出内核</span></span></strong></h2><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">__TEXT_EXEC:__text:FFFFFFF00813197C exception_return_unint_tpidr_x3_dont_trash_x18</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOV             X0, SP</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">LDR             W2, [X0,#arg_110]</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">LDR             X1, [X0,#arg_108]</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">LDP             X16, X17, [X0,#arg_88]</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOV             X22, X3</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOV             X23, X4</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOV             X24, X5</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOV             X20, X1</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOV             X21, X2</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">LDR             X3, [X0,#arg_F8]</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOV             X4, X16</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MOV             X5, X17</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">BL              _ml_check_signed_state</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">在退出内核到用户态前，需要再次校验下当前进程的</span><span style="font-family:Calibri;">thread state</span><span style="font-family:宋体;">，如果发生错误，则</span><span style="font-family:Calibri;">panic</span><span style="font-family:宋体;">系统。</span></span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">LDR             X1, [X2,#0x510]</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">LDR             X2, [X2,#0x4F8]</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">LDR             X3, [X2,#0x208]</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">CMP             X1, X3</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">B.EQ            loc_FFFFFFF008131A3C</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MSR             #0, c2, c1, #0, X1 ; APIAKeyLo_EL1</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">ADD             X3, X1, #1</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MSR             #0, c2, c1, #1, X3 ; APIAKeyHi_EL1</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">ADD             X3, X3, #1</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MSR             #0, c2, c2, #0, X3 ; APDAKeyLo_EL1</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">ADD             X3, X3, #1</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">MSR             #0, c2, c2, #1, X3 ; APDAKeyHi_EL1</span></p><p style="text-align:left;"><span style="font-family:Calibri;font-size:14px;">STR             X1, [X2,#0x208]</span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">恢复进程使用的</span><span style="font-family:Calibri;">pac key</span><span style="font-family:宋体;">。</span></span></p><p style="text-indent:28px;text-align:left;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h1><strong><span style="font-family:宋体;font-size:29px;"><span style="font-family:Calibri;">5 </span><span style="font-family:宋体;">进程</span><span style="font-family:Calibri;">thread state pac</span><span style="font-family:宋体;">的初始化</span></span></strong></h1><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">前面提到在进程切换时，需要验证进程的</span><span style="font-family:Calibri;">thread state pac</span><span style="font-family:宋体;">，那么它是在何时初始化的呢？</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">答案在进程初始化</span><span style="font-family:Calibri;">stack</span><span style="font-family:宋体;">时进行</span><span style="font-family:Calibri;">thread state</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">pac</span><span style="font-family:宋体;">计算。</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">_machine_stack_attach</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">STR             X1, [X0,#0x78] ; struct arm_kernel_saved_state-&gt;pc</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             X2, #0x100004</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">STR             W2, [X0,#0x80] ; struct arm_kernel_saved_state-&gt;cpsr</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">ADRL            X3, _thread_continue</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">STR             X3, [X0,#0x68] ; struct arm_kernel_saved_state-&gt;lr</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             X4, XZR</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             X5, XZR</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">STP             X4, X5, [X0]</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             X6, X30</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">BL              _ml_sign_kernel_thread_state ; sign thread state.</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;"><br/></span></span></p><h1><span style="font-family:宋体;font-size:29px;">6. </span><strong><span style="font-family:宋体;font-size:29px;"><span style="font-family:Calibri;">Ppl</span><span style="font-family:宋体;">相关</span></span></strong></h1><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">Ppl</span><span style="font-family:宋体;">提供了两个服务用来给用户进程数据进行签名与验签。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">6.1 _pmap_sign_user_ptr</span></span></strong></h2><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">__TEXT_EXEC:__text:FFFFFFF007B609A0 _pmap_sign_user_ptr</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">ADD             X29, SP, #0x30</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             X19, X0</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MRS             X23, #3, c4, c2, #1 ; DAIFSet</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">TBNZ            W23, #7, loc_FFFFFFF007B609D0 ; TPIDR_EL1</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MSR             #6, #7</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">关闭</span><span style="font-family:Calibri;">DAIF</span><span style="font-family:宋体;">中断</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MRS             X8, #0, c13, c0, #4 ; TPIDR_EL1</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">LDR             X8, [X8,#0x4F8]</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">LDR             X20, [X8,#0x208]</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             W0, #0</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             X1, X3</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">BL              </span></span><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:Calibri;">_ml_set_kernelkey_enabled</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">将</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">作为参数传递给</span></span><span style="font-family:Calibri;font-size:14px;">_ml_set_kernelkey_enabled</span><span style="font-family:宋体;font-size:14px;">。</span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">__TEXT_EXEC:__text:FFFFFFF008139374 _ml_set_kernelkey_enabled               </span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MRS             X2, #0, c13, c0, #4 ; TPIDR_EL1</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">LDR             X2, [X2,#0x4F8]</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">LDR             X3, [X2,#0x208]</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">CMP             X1, X3</span></span></p><p><span style="font-family:宋体;font-size:14px;">B. </span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">EQ            loc_FFFFFFF0081393A8 ; S3_4_C15_C0_4</span></span></p><p style="margin-left:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">如果当前进程的</span><span style="font-family:Calibri;">pac key</span><span style="font-family:宋体;">和用户传递进来的</span><span style="font-family:Calibri;">pac key</span><span style="font-family:宋体;">相等，则直接跳转到后面。</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MSR             #0, c2, c1, #0, X1 ; APIAKeyLo_EL1</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">ADD             X3, X1, #1</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MSR             #0, c2, c1, #1, X3 ; APIAKeyHi_EL1</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">ADD             X3, X3, #1</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MSR             #0, c2, c2, #0, X3 ; APDAKeyLo_EL1</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">ADD             X3, X3, #1</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MSR             #0, c2, c2, #1, X3 ; APDAKeyHi_EL1</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">STR             X1, [X2,#0x208]</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">依次切换系统寄存器</span><span style="font-family:Calibri;">APIAKey_EL1</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">APDAKey_EL1</span><span style="font-family:宋体;">，可以看到</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">只用</span><span style="font-family:Calibri;">key A</span><span style="font-family:宋体;">来签名用户代码或数据。</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MRS             X1, #4, c15, c0, #4 ; S3_4_C15_C0_4</span></span></p><p><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:Calibri;">ORR             X3, X1, #4</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">AND             X2, X1, #0xFFFFFFFFFFFFFFFB</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">CMP             W0, #0</span></span></p><p><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:Calibri;">CSEL            X1, X2, X3, EQ</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MSR             #4, c15, c0, #4, X1 ; S3_4_C15_C0_4</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">ISB</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">RET</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">如果传递给</span><span style="font-family:Calibri;">_ml_set_kernelkey_enabled</span><span style="font-family:宋体;">函数的第一个参数为</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">，那么将</span><span style="font-family:Calibri;">S3_4_C15_C0_4</span><span style="font-family:宋体;">的第</span><span style="font-family:Calibri;">3</span><span style="font-family:宋体;">个</span><span style="font-family:Calibri;">bit</span><span style="font-family:宋体;">置</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">，否则置</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">回到</span><span style="font-family:Calibri;">_pmap_sign_user_ptr</span></span></p><p><span style="font-family:Calibri;font-size:14px;">CMP             W22, #2</span></p><p><span style="font-family:Calibri;font-size:14px;">B.EQ            loc_FFFFFFF007B609FC</span></p><p><span style="font-family:Calibri;font-size:14px;">CBNZ            W22, loc_FFFFFFF007B60A34</span></p><p><span style="font-family:Calibri;font-size:14px;">PACIA           X19, X21</span></p><p><span style="font-family:Calibri;font-size:14px;">B               loc_FFFFFFF007B60A00</span></p><p><span style="font-family:Calibri;font-size:14px;">PACDA           X19, X21</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">如果第</span><span style="font-family:Calibri;">2</span><span style="font-family:宋体;">个参数为</span><span style="font-family:Calibri;">2</span><span style="font-family:宋体;">，则使用</span><span style="font-family:Calibri;">pacda</span><span style="font-family:宋体;">对第</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">个参数签名，如果为</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">，使用</span><span style="font-family:Calibri;">pacia</span><span style="font-family:宋体;">进行签名，如果不是</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">，也不是</span><span style="font-family:Calibri;">2</span><span style="font-family:宋体;">， 则</span><span style="font-family:Calibri;">panic</span><span style="font-family:宋体;">系统。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W0, #1</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X1, X20</span></p><p><span style="font-family:Calibri;font-size:14px;">BL              _ml_set_kernelkey_enabled</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">将</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">作为参数传递给</span></span><span style="font-family:Calibri;font-size:14px;">_ml_set_kernelkey_enabled</span><span style="font-family:宋体;font-size:14px;">。</span></p><p><span style="font-family:Calibri;font-size:14px;">_ml_set_kernelkey_enabled</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">(0, pac_key)</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">...</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">Pacia/pacib</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">...</span></span></p><p><span style="font-family:Calibri;font-size:14px;">_ml_set_kernelkey_enabled</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">(1, pac_key)</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">因此我们可以推测出</span><span style="font-family:Calibri;">S3_4_C15_C0_4</span><span style="font-family:宋体;">的第</span><span style="font-family:Calibri;">2</span><span style="font-family:宋体;">个</span><span style="font-family:Calibri;">bit</span><span style="font-family:宋体;">为上锁功能， </span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">代表上锁，</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">代表解锁。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">6.2 _pmap_auth_user_ptr</span></span></strong></h2><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">AUTIA           X19, X21</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">B               loc_FFFFFFF007B60AD4</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">AUTDA           X19, X21</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">B               loc_FFFFFFF007B60AD4</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">AUTDB           X19, X21</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">B               loc_FFFFFFF007B60AD4</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">AUTIB           X19, X21</span></span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">这里我们看到</span><span style="font-family:Calibri;">_pmap_auth_user_ptr</span><span style="font-family:宋体;">在验签的时候还使用了</span><span style="font-family:Calibri;">key b</span><span style="font-family:宋体;">，而</span></span><span style="font-family:Calibri;font-size:14px;">_ml_set_kernelkey_enabled</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">只设置了</span><span style="font-family:Calibri;">key a</span><span style="font-family:宋体;">， 说明了</span><span style="font-family:Calibri;">key a</span><span style="font-family:宋体;">是进程相关的，而</span><span style="font-family:Calibri;">key b</span><span style="font-family:宋体;">是进程不相关的， </span><span style="font-family:Calibri;">XNU</span><span style="font-family:宋体;">源码里定义了以下几种类型的</span><span style="font-family:Calibri;">pac key</span><span style="font-family:宋体;">：</span></span></p><p><span style="font-family:Calibri;font-size:14px;">EXTERNAL_HEADERS/ptrauth.h</span></p><p><span style="font-family:Calibri;font-size:14px;">typedef enum {</span></p><p><span style="font-family:Calibri;font-size:14px;">  ptrauth_key_asia = 0,</span></p><p><span style="font-family:Calibri;font-size:14px;">  ptrauth_key_asib = 1,</span></p><p><span style="font-family:Calibri;font-size:14px;">  ptrauth_key_asda = 2,</span></p><p><span style="font-family:Calibri;font-size:14px;">  ptrauth_key_asdb = 3,</span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">  /* A process-independent key which can be used to sign code pointers.</span></p><p><span style="font-family:Calibri;font-size:14px;">     Signing and authenticating with this key is a no-op in processes</span></p><p><span style="font-family:Calibri;font-size:14px;">     which disable ABI pointer authentication. */</span></p><p><span style="font-family:Calibri;font-size:14px;">  </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">ptrauth_key_process_independent_code = ptrauth_key_asia</span><span style="font-family:Calibri;font-size:14px;">,</span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">  /* A process-specific key which can be used to sign code pointers.</span></p><p><span style="font-family:Calibri;font-size:14px;">     Signing and authenticating with this key is enforced even in processes</span></p><p><span style="font-family:Calibri;font-size:14px;">     which disable ABI pointer authentication. */</span></p><p><span style="font-family:Calibri;font-size:14px;">  </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">ptrauth_key_process_dependent_code = ptrauth_key_asib</span><span style="font-family:Calibri;font-size:14px;">,</span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">  /* A process-independent key which can be used to sign data pointers.</span></p><p><span style="font-family:Calibri;font-size:14px;">     Signing and authenticating with this key is a no-op in processes</span></p><p><span style="font-family:Calibri;font-size:14px;">     which disable ABI pointer authentication. */</span></p><p><span style="font-family:Calibri;font-size:14px;"> </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"> ptrauth_key_process_independent_data = ptrauth_key_asda</span><span style="font-family:Calibri;font-size:14px;">,</span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">  /* A process-specific key which can be used to sign data pointers.</span></p><p><span style="font-family:Calibri;font-size:14px;">     Signing and authenticating with this key is a no-op in processes</span></p><p><span style="font-family:Calibri;font-size:14px;">     which disable ABI pointer authentication. */</span></p><p><span style="font-family:Calibri;font-size:14px;">  </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">ptrauth_key_process_dependent_data = ptrauth_key_asdb</span><span style="font-family:Calibri;font-size:14px;">,</span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">  /* The key used to sign C function pointers.</span></p><p><span style="font-family:Calibri;font-size:14px;">     The extra data is always 0. */</span></p><p><span style="font-family:Calibri;font-size:14px;">  </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">ptrauth_key_function_pointer = ptrauth_key_process_independent_code</span><span style="font-family:Calibri;font-size:14px;">,</span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">  /* The key used to sign return addresses on the stack.</span></p><p><span style="font-family:Calibri;font-size:14px;">     The extra data is based on the storage address of the return address.</span></p><p><span style="font-family:Calibri;font-size:14px;">     On ARM64, that is always the storage address of the return address plus 8</span></p><p><span style="font-family:Calibri;font-size:14px;">     (or, in other words, the value of the stack pointer on function entry) */</span></p><p><span style="font-family:Calibri;font-size:14px;">  </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">ptrauth_key_return_address = ptrauth_key_process_dependent_code</span><span style="font-family:Calibri;font-size:14px;">,</span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">  /* The key used to sign frame pointers on the stack.</span></p><p><span style="font-family:Calibri;font-size:14px;">     The extra data is based on the storage address of the frame pointer.</span></p><p><span style="font-family:Calibri;font-size:14px;">     On ARM64, that is always the storage address of the frame pointer plus 16</span></p><p><span style="font-family:Calibri;font-size:14px;">     (or, in other words, the value of the stack pointer on function entry) */</span></p><p><span style="font-family:Calibri;font-size:14px;"> </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"> ptrauth_key_frame_pointer = ptrauth_key_process_dependent_data</span><span style="font-family:Calibri;font-size:14px;">,</span></p><p><span style="font-family:Calibri;font-size:14px;">  /* The key used to sign block function pointers, including:</span></p><p><span style="font-family:Calibri;font-size:14px;">       invocation functions,</span></p><p><span style="font-family:Calibri;font-size:14px;">       block object copy functions,</span></p><p><span style="font-family:Calibri;font-size:14px;">       block object destroy functions,</span></p><p><span style="font-family:Calibri;font-size:14px;">       __block variable copy functions, and</span></p><p><span style="font-family:Calibri;font-size:14px;">       __block variable destroy functions.</span></p><p><span style="font-family:Calibri;font-size:14px;">     The extra data is always the address at which the function pointer</span></p><p><span style="font-family:Calibri;font-size:14px;">     is stored.</span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">     Note that block object pointers themselves (i.e. the direct</span></p><p><span style="font-family:Calibri;font-size:14px;">     representations of values of block-pointer type) are not signed. */</span></p><p><span style="font-family:Calibri;font-size:14px;">  ptrauth_key_block_function = ptrauth_key_asia,</span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">  /* The key used to sign C++ v-table pointers.</span></p><p><span style="font-family:Calibri;font-size:14px;">     The extra data is always 0. */</span></p><p><span style="font-family:Calibri;font-size:14px;">  ptrauth_key_cxx_vtable_pointer = ptrauth_key_asda,</span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">  /* Other pointers signed under the ABI use private ABI rules. */</span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">} ptrauth_key;</span></p>



<p><a href="2247483774">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=37b20f84&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg4NjU1NDU4MA%3D%3D%26mid%3D2247483774%26idx%3D1%26sn%3D3f1d304fe16cb29afe98ace4173bb658%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Mon, 06 Dec 2021 11:09:00 +0800</pubDate>
    </item>
    <item>
      <title>Linux与XNU的KPTI实现解读</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg4NjU1NDU4MA==&amp;mid=2247483769&amp;idx=1&amp;sn=3f6fae0b609addcd9b0aa5c736eef0e0</link>
      <description>Linux与XNU的kpti实现解读</description>
      <content:encoded><![CDATA[<p>
原创 <span>wzt</span> <span>2021-11-29 14:08</span> <span style="display: inline-block;"></span>
</p>

<p>Linux与XNU的kpti实现解读</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=cff4060f&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F4iaJia7Cvd3PBiaibGD05SBSibmxHQZwP0yTHUDLGAtbyTq46CHibv7A3VNkcDHxBIKpaWXlB1n7xfeIFUROr1prkFibw%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<h1><span style="font-family:宋体;font-size:29px;">1. </span><strong><span style="font-family:宋体;font-size:29px;">概述</span></strong></h1><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">由于</span><span style="font-family:Calibri;">cpu</span><span style="font-family:宋体;">的指令预取存在漏洞，可以从</span><span style="font-family:Calibri;">el0</span><span style="font-family:宋体;">直接访问</span><span style="font-family:Calibri;">el1</span><span style="font-family:宋体;">内容，主流</span><span style="font-family:Calibri;">os</span><span style="font-family:宋体;">对其缓解措施就是限制</span><span style="font-family:Calibri;">el0</span><span style="font-family:宋体;">能读取的</span><span style="font-family:Calibri;">el1</span><span style="font-family:宋体;">代码范围， 注意程序运行在</span><span style="font-family:Calibri;">el0</span><span style="font-family:宋体;">时，并不能直接关闭</span><span style="font-family:Calibri;">el1</span><span style="font-family:宋体;">的所有代码访问路径，一个原因是程序运行过程会产生错误，需要</span><span style="font-family:Calibri;">el1</span><span style="font-family:宋体;">的异常处理逻辑来接管，另一个原因是程序需要主动使用</span><span style="font-family:Calibri;">svc</span><span style="font-family:宋体;">请求</span><span style="font-family:Calibri;">el1</span><span style="font-family:宋体;">的系统服务，同样还是会被异常处理逻辑来接管。为此</span><span style="font-family:Calibri;">linux</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">xnu</span><span style="font-family:宋体;">使用了两种不同的方案来实现</span><span style="font-family:Calibri;">el1</span><span style="font-family:宋体;">的页表隔离。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h1><span style="font-family:宋体;font-size:29px;">2. </span><strong><span style="font-family:宋体;font-size:29px;"><span style="font-family:Calibri;">Linux kpti</span><span style="font-family:宋体;">实现</span></span></strong></h1><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">linux</span><span style="font-family:宋体;">的做法是在</span><span style="font-family:Calibri;">el0 level</span><span style="font-family:宋体;">上提供一个简单的异常处理程序</span><span style="font-family:Calibri;">trampline</span><span style="font-family:宋体;">以及新的</span><span style="font-family:Calibri;">ttbr1_el1</span><span style="font-family:宋体;">页表，每次从</span><span style="font-family:Calibri;">el0</span><span style="font-family:宋体;">进入</span><span style="font-family:Calibri;">el1</span><span style="font-family:宋体;">时，切换</span><span style="font-family:Calibri;">vbar_el1</span><span style="font-family:宋体;">的地址以及</span><span style="font-family:Calibri;">ttbr1_el1</span><span style="font-family:宋体;">的地址为内核使用的异常处理地址和页表地址，每次从</span><span style="font-family:Calibri;">el1</span><span style="font-family:宋体;">退回</span><span style="font-family:Calibri;">el0</span><span style="font-family:宋体;">时，再次切换</span><span style="font-family:Calibri;">vbar_el1</span><span style="font-family:宋体;">为</span><span style="font-family:Calibri;">trampline</span><span style="font-family:宋体;">的地址以及切换新的</span><span style="font-family:Calibri;">ttbr1_el1</span><span style="font-family:宋体;">地址。</span><span style="font-family:Calibri;">trampline</span><span style="font-family:宋体;">的代码段很小，只会映射</span><span style="font-family:Calibri;">el1</span><span style="font-family:宋体;">异常处理代码的范围，这样新的</span><span style="font-family:Calibri;">ttbr_el1</span><span style="font-family:宋体;">的页表占用空间也会非常小。</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">./arch/arm64/kernel/vmlinux.lds.S</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">#ifdef CONFIG_UNMAP_KERNEL_AT_EL0</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">#define TRAMP_TEXT                                      \</span></span></p><p><span style="font-family:宋体;font-size:14px;">        <span style="font-family:Calibri;">. = ALIGN(PAGE_SIZE);                           \</span></span></p><p><span style="font-family:宋体;font-size:14px;">        <span style="font-family:Calibri;">__entry_tramp_text_start = .;                   \</span></span></p><p><span style="font-family:宋体;font-size:14px;">        <span style="font-family:Calibri;">*(.entry.tramp.text)                            \</span></span></p><p><span style="font-family:宋体;font-size:14px;">        <span style="font-family:Calibri;">. = ALIGN(PAGE_SIZE);                           \</span></span></p><p><span style="font-family:宋体;font-size:14px;">        <span style="font-family:Calibri;">__entry_tramp_text_end = .;</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">内核的链接脚本里预先划分出</span><span style="font-family:Calibri;">trampline</span><span style="font-family:宋体;">的代码空间。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">        idmap_pg_dir = .;</span></p><p><span style="font-family:Calibri;font-size:14px;">        . += IDMAP_DIR_SIZE;</span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">#ifdef CONFIG_UNMAP_KERNEL_AT_EL0</span></p><p><span style="font-family:Calibri;font-size:14px;">        tramp_pg_dir = .;</span></p><p><span style="font-family:Calibri;font-size:14px;">        . += PAGE_SIZE;</span></p><p><span style="font-family:Calibri;font-size:14px;">#endif</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">trampline</span><span style="font-family:宋体;">的页表地址紧挨在</span></span><span style="font-family:Calibri;font-size:14px;">idmap_pg_dir</span><span style="font-family:宋体;font-size:14px;">后面。</span></p><p><span style="font-family:Calibri;font-size:14px;">./arch/arm64/kernel/entry.S</span></p><p><span style="font-family:Calibri;font-size:14px;">.pushsection &#34;.entry.tramp.text&#34;, &#34;ax&#34;</span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">.macro tramp_map_kernel, tmp</span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;">mrs     \tmp, ttbr1_el1</span></p><p><span style="font-family:Calibri;font-size:14px;">    add     \tmp, \tmp, #(PAGE_SIZE + RESERVED_TTBR0_SIZE)</span></p><p><span style="font-family:Calibri;font-size:14px;">    bic     \tmp, \tmp, #USER_ASID_FLAG</span></p><p><span style="font-family:Calibri;font-size:14px;">    msr     ttbr1_el1, \tmp</span></p><p><span style="font-family:Calibri;font-size:14px;">.endm</span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">.macro tramp_unmap_kernel, tmp</span></p><p><span style="font-family:Calibri;font-size:14px;">    mrs     \tmp, ttbr1_el1</span></p><p><span style="font-family:Calibri;font-size:14px;">    sub     \tmp, \tmp, #(PAGE_SIZE + RESERVED_TTBR0_SIZE)</span></p><p><span style="font-family:Calibri;font-size:14px;">    orr     \tmp, \tmp, #USER_ASID_FLAG</span></p><p><span style="font-family:Calibri;font-size:14px;">    msr     ttbr1_el1, \tmp</span></p><p><span style="font-family:Calibri;font-size:14px;">.endm</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">宏</span><span style="font-family:Calibri;font-size:14px;">tramp_map_kernel</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">用来每次进入内核时，更新内核的</span><span style="font-family:Calibri;">ttbr1_el1</span><span style="font-family:宋体;">地址。宏</span></span><span style="font-family:Calibri;font-size:14px;">tramp_unmap_kernel</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">用来每次退出内核时，切换</span><span style="font-family:Calibri;">trampline</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">ttbr_el1</span><span style="font-family:宋体;">地址。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">        .macro tramp_ventry, regsize = 64</span></p><p><span style="font-family:Calibri;font-size:14px;">        .align  7</span></p><p><span style="font-family:Calibri;font-size:14px;">1:</span></p><p><span style="font-family:Calibri;font-size:14px;">        .if     \regsize == 64</span></p><p><span style="font-family:Calibri;font-size:14px;">        msr     tpidrro_el0, x30        // Restored in kernel_ventry</span></p><p><span style="font-family:Calibri;font-size:14px;">        .endif</span></p><p><span style="font-family:Calibri;font-size:14px;">        bl      2f</span></p><p><span style="font-family:Calibri;font-size:14px;">        b       .</span></p><p><span style="font-family:Calibri;font-size:14px;">2:</span></p><p><span style="font-family:Calibri;font-size:14px;">tramp_map_kernel        x30</span></p><p><span style="font-family:Calibri;font-size:14px;">#ifdef CONFIG_RANDOMIZE_BASE</span></p><p><span style="font-family:Calibri;font-size:14px;">        adr     x30, tramp_vectors + PAGE_SIZE</span></p><p><span style="font-family:Calibri;font-size:14px;">alternative_insn isb, nop, ARM64_WORKAROUND_QCOM_FALKOR_E1003</span></p><p><span style="font-family:Calibri;font-size:14px;">        ldr     x30, [x30]</span></p><p><span style="font-family:Calibri;font-size:14px;">#else</span></p><p><span style="font-family:Calibri;font-size:14px;">        ldr     x30, </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">=vectors</span></p><p><span style="font-family:Calibri;font-size:14px;">#endif</span></p><p><span style="font-family:Calibri;font-size:14px;">        msr     vbar_el1, x30</span></p><p><span style="font-family:Calibri;font-size:14px;">        add     x30, x30, #(1b - tramp_vectors)</span></p><p><span style="font-family:Calibri;font-size:14px;">        isb</span></p><p><span style="font-family:Calibri;font-size:14px;">        ret</span></p><p><span style="font-family:Calibri;font-size:14px;">.endm</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">宏</span><span style="font-family:Calibri;font-size:14px;">tramp_ventry</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">是</span><span style="font-family:Calibri;">el1</span><span style="font-family:宋体;">异常处理的入口地址，首先调用了</span></span><span style="font-family:Calibri;font-size:14px;">tramp_map_kerne</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">l</span><span style="font-family:宋体;">切换内核的</span><span style="font-family:Calibri;">ttbr1_el1</span><span style="font-family:宋体;">，紧接着切换</span></span><span style="font-family:Calibri;font-size:14px;">vbar_el1</span><span style="font-family:宋体;font-size:14px;">为内核的异常处理地址</span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">=vectors</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">，所以</span><span style="font-family:Calibri;">trampline</span><span style="font-family:宋体;">的作用顾名思义只起到跳转的作用，真正对异常处理的流程还是要通过内核来接管。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">        .macro tramp_exit, regsize = 64</span></p><p><span style="font-family:Calibri;font-size:14px;">        adr     x30, tramp_vectors</span></p><p><span style="font-family:Calibri;font-size:14px;">        msr     vbar_el1, x30</span></p><p><span style="font-family:Calibri;font-size:14px;">        tramp_unmap_kernel      x30</span></p><p><span style="font-family:Calibri;font-size:14px;">        .if     \regsize == 64</span></p><p><span style="font-family:Calibri;font-size:14px;">        mrs     x30, far_el1</span></p><p><span style="font-family:Calibri;font-size:14px;">        .endif</span></p><p><span style="font-family:Calibri;font-size:14px;">        eret</span></p><p><span style="font-family:Calibri;font-size:14px;">        Sb</span></p><p><span style="font-family:Calibri;font-size:14px;">        .endm</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">每次退出异常处理时，首先调用</span><span style="font-family:Calibri;font-size:14px;">tramp_unmap_kern</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">el</span><span style="font-family:宋体;">更新</span><span style="font-family:Calibri;">trampline</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">ttbr1_el1</span><span style="font-family:宋体;">页表地址，然后更新</span><span style="font-family:Calibri;">vbar_el1</span><span style="font-family:宋体;">为</span><span style="font-family:Calibri;">trampline</span><span style="font-family:宋体;">使用的</span></span><span style="font-family:Calibri;font-size:14px;">tramp_vectors</span><span style="font-family:宋体;font-size:14px;">异常处理入口。</span></p><p><span style="font-family:Calibri;font-size:14px;">ENTRY(tramp_vectors)</span></p><p><span style="font-family:Calibri;font-size:14px;">        .space  0x400</span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">        tramp_ventry</span></p><p><span style="font-family:Calibri;font-size:14px;">        tramp_ventry</span></p><p><span style="font-family:Calibri;font-size:14px;">        tramp_ventry</span></p><p><span style="font-family:Calibri;font-size:14px;">        tramp_ventry</span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">        tramp_ventry    32</span></p><p><span style="font-family:Calibri;font-size:14px;">        tramp_ventry    32</span></p><p><span style="font-family:Calibri;font-size:14px;">        tramp_ventry    32</span></p><p><span style="font-family:Calibri;font-size:14px;">        tramp_ventry    32</span></p><p><span style="font-family:Calibri;font-size:14px;">END(tramp_vectors)</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">可以看到</span><span style="font-family:Calibri;">trampline</span><span style="font-family:宋体;">的异常处理地址，只需填充了</span><span style="font-family:Calibri;">0x400</span><span style="font-family:宋体;">偏移，也就是来自</span><span style="font-family:Calibri;">el0</span><span style="font-family:宋体;">的同步类型的异常处理，因为</span><span style="font-family:Calibri;">trampline</span><span style="font-family:宋体;">的存在仅是为了服务来自</span><span style="font-family:Calibri;">el0</span><span style="font-family:宋体;">的异常处理请求。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h1><span style="font-family:宋体;font-size:29px;">3. </span><strong><span style="font-family:宋体;font-size:29px;"><span style="font-family:Calibri;">XNU kpti</span><span style="font-family:宋体;">实现</span></span></strong></h1><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">我们看到</span><span style="font-family:Calibri;">linux</span><span style="font-family:宋体;">为了在</span><span style="font-family:Calibri;">el0</span><span style="font-family:宋体;">隔离</span><span style="font-family:Calibri;">el1</span><span style="font-family:宋体;">的代码，使用了一个新的代码段叫</span><span style="font-family:Calibri;">trampline</span><span style="font-family:宋体;">，一个新的页表</span></span><span style="font-family:Calibri;font-size:14px;">tramp_pg_dir</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">，每次进入内核与退出内核时都要切换</span><span style="font-family:Calibri;">vbar_el1</span><span style="font-family:宋体;">以及</span><span style="font-family:Calibri;">ttbr1_el1</span><span style="font-family:宋体;">。这样频繁的切换这两个寄存器，性能肯定会受到影响。而</span><span style="font-family:Calibri;">XNU</span><span style="font-family:宋体;">利用了一个更聪明更巧妙的做法来使性能损失达到最小。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">XNU</span><span style="font-family:宋体;">通过使</span><span style="font-family:Calibri;">tcr.T1SZ</span><span style="font-family:宋体;">字段减去</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">，使从内核返回用户空间时，内核的虚拟地址空间减半，也就是缩减了内核空间的大小，这样即使</span><span style="font-family:Calibri;">el0</span><span style="font-family:宋体;">程序利用</span><span style="font-family:Calibri;">cpu</span><span style="font-family:宋体;">漏洞，也只能读取较低的内核地址空间，没有关键的内核数据。每次从用户空间进入内核时，在将</span><span style="font-family:Calibri;">tcr.T1SZ</span><span style="font-family:宋体;">字段加</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">，恢复整个的内核地址空间。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">./osfmk/arm64/locore.s</span></p><p><span style="font-family:Calibri;font-size:14px;">.macro MAP_KERNEL</span></p><p><span style="font-family:Calibri;font-size:14px;">        mrs             x18, TTBR0_EL1</span></p><p><span style="font-family:Calibri;font-size:14px;">        orr             x18, x18, #(1 &lt;&lt; TTBR_ASID_SHIFT)</span></p><p><span style="font-family:Calibri;font-size:14px;">        msr             TTBR0_EL1, x18</span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">        MOV64           x18, </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">TCR_EL1_BOOT</span></p><p><span style="font-family:Calibri;font-size:14px;">        msr             </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">TCR_EL1</span><span style="font-family:Calibri;font-size:14px;">, x18</span></p><p><span style="font-family:Calibri;font-size:14px;">        isb             sy</span></p><p><span style="font-family:Calibri;font-size:14px;">.endmacro</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">每次进入内核时跟新</span><span style="font-family:Calibri;">TCR_EL1</span><span style="font-family:宋体;">。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">        /* Update TCR to unmap the kernel. */</span></p><p><span style="font-family:Calibri;font-size:14px;">        MOV64           x18, </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">TCR_EL1_USER</span></p><p><span style="font-family:Calibri;font-size:14px;">        msr             </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">TCR_EL1</span><span style="font-family:Calibri;font-size:14px;">, x18</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">每次从异常处理退出内核时，修改</span><span style="font-family:Calibri;">TCR_EL1</span><span style="font-family:宋体;">缩减内核地址空间。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">osfmk/arm64/proc_reg.h</span></p><p><span style="font-family:Calibri;font-size:14px;">#define TCR_EL1_BOOT (TCR_EL1_BASE | (</span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">T1SZ_BOOT</span><span style="font-family:Calibri;font-size:14px;"> &lt;&lt; TCR_T1SZ_SHIFT) | (TCR_TG0_GRANULE_SIZE))</span></p><p><span style="font-family:Calibri;font-size:14px;">#define </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">T1SZ_USER (T1SZ_BOOT + 1)</span></p><p><span style="font-family:Calibri;font-size:14px;">#define TCR_EL1_USER (TCR_EL1_BASE | (</span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">T1SZ_USER</span><span style="font-family:Calibri;font-size:14px;"> &lt;&lt; TCR_T1SZ_SHIFT) | (TCR_TG0_GRANULE_SIZE))</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">同样对于在</span><span style="font-family:Calibri;">el0</span><span style="font-family:宋体;">时触发的异常处理地址，</span><span style="font-family:Calibri;">XNU</span><span style="font-family:宋体;">利用了一个</span><span style="font-family:Calibri;">tricky</span><span style="font-family:宋体;">技巧，将内核态的异常处理地址的</span></span><strong><span style="font-family: 宋体;font-size: 14px;background: rgb(255, 255, 0);"><span style="font-family:宋体;">虚拟地址</span></span></strong><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">和在</span><span style="font-family:Calibri;">el0</span><span style="font-family:宋体;">时触发的异常处理的</span></span><strong><span style="font-family: 宋体;font-size: 14px;background: rgb(255, 255, 0);"><span style="font-family:宋体;">虚拟地址</span></span></strong><span style="font-family:宋体;font-size:14px;">，都映射到了内核原有的异常处理地址的</span><strong><span style="font-family: 宋体;font-size: 14px;background: rgb(255, 255, 0);"><span style="font-family:宋体;">物理地址</span></span></strong><span style="font-family: 宋体;font-size: 14px;">，</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">并且</span><span style="font-family:Calibri;">el0</span><span style="font-family:宋体;">时触发的异常处理的</span></span><span style="font-family: 宋体;font-size: 14px;">虚拟地址正好选在了内核地址空间的一半位置处。</span></p><p><span style="font-family: 宋体;font-size: 14px;"><span style="font-family:Calibri;">./osfmk/arm64/arm_vm_init.c</span></span></p><p><span style="font-family: 宋体;font-size: 14px;"><span style="font-family:Calibri;">static void</span></span></p><p><span style="font-family: 宋体;font-size: 14px;"><span style="font-family:Calibri;">arm_vm_prepare_kernel_el0_mappings(bool alloc_only)</span></span></p><p><span style="font-family: 宋体;font-size: 14px;"><span style="font-family:Calibri;">{</span></span></p><p><span style="font-family: 宋体;font-size: 14px;">        <span style="font-family:Calibri;">pt_entry_t pte = 0;</span></span></p><p><span style="font-family: 宋体;font-size: 14px;">        <span style="font-family:Calibri;">vm_offset_t start = ((vm_offset_t)&amp;ExceptionVectorsBase) &amp; ~PAGE_MASK;</span></span></p><p><span style="font-family: 宋体;font-size: 14px;">        <span style="font-family:Calibri;">vm_offset_t end = (((vm_offset_t)&amp;ExceptionVectorsEnd) + PAGE_MASK) &amp; ~PAGE_MASK;</span></span></p><p><span style="font-family: 宋体;font-size: 14px;">        <span style="font-family:Calibri;">vm_offset_t cur = 0;</span></span></p><p><span style="font-family: 宋体;font-size: 14px;">        <span style="font-family:Calibri;">vm_offset_t cur_fixed = 0;</span></span></p><p><span style="font-family: 宋体;font-size: 14px;"> </span></p><p><span style="font-family: 宋体;font-size: 14px;">        <span style="font-family:Calibri;">for (cur = start, cur_fixed =</span></span><span style="font-family: 宋体;font-size: 14px;background: rgb(255, 255, 0);"> <span style="font-family:Calibri;">ARM_KERNEL_PROTECT_EXCEPTION_START</span></span><span style="font-family: 宋体;font-size: 14px;"><span style="font-family:Calibri;">; cur &lt; end; cur += ARM_PGBYTES, cur_fixed += ARM_PGBYTES) {</span></span></p><p><span style="font-family: 宋体;font-size: 14px;">                <span style="font-family:Calibri;">if (!alloc_only) {</span></span></p><p><span style="font-family: 宋体;font-size: 14px;">                        <span style="font-family:Calibri;">pte = arm_vm_kernel_pte(cur);</span></span></p><p><span style="font-family: 宋体;font-size: 14px;">                <span style="font-family:Calibri;">}</span></span></p><p><span style="font-family: 宋体;font-size: 14px;"> </span></p><p><span style="font-family: 宋体;font-size: 14px;">                <span style="font-family:Calibri;">arm_vm_kernel_el1_map(cur_fixed, pte);</span></span></p><p><span style="font-family: 宋体;font-size: 14px;">                </span><span style="font-family: 宋体;font-size: 14px;background: rgb(255, 255, 0);"><span style="font-family:Calibri;">arm_vm_kernel_el0_map(cur_fixed, pte);</span></span></p><p><span style="font-family: 宋体;font-size: 14px;">        <span style="font-family:Calibri;">}</span></span></p><p><span style="font-family: 宋体;font-size: 14px;"> </span></p><p><span style="font-family: 宋体;font-size: 14px;">        <span style="font-family:Calibri;">__builtin_arm_dmb(DMB_ISH);</span></span></p><p><span style="font-family: 宋体;font-size: 14px;">        <span style="font-family:Calibri;">__builtin_arm_isb(ISB_SY);</span></span></p><p><span style="font-family: 宋体;font-size: 14px;"> </span></p><p><span style="font-family: 宋体;font-size: 14px;">        <span style="font-family:Calibri;">if (!alloc_only) {</span></span></p><p><span style="font-family: 宋体;font-size: 14px;">                <span style="font-family:Calibri;">set_vbar_el1(ARM_KERNEL_PROTECT_EXCEPTION_START);</span></span></p><p><span style="font-family: 宋体;font-size: 14px;">                <span style="font-family:Calibri;">__builtin_arm_isb(ISB_SY);</span></span></p><p><span style="font-family: 宋体;font-size: 14px;">        <span style="font-family:Calibri;">}</span></span></p><p><span style="font-family: 宋体;font-size: 14px;"><span style="font-family:Calibri;">}</span></span></p><p><span style="font-family: 宋体;font-size: 14px;"><span style="font-family:Calibri;">osfmk/arm/pmap.h</span></span></p><p><span style="font-family: 宋体;font-size: 14px;"><span style="font-family:Calibri;">#define ARM_KERNEL_PROTECT_EXCEPTION_START ((~((ARM_TT_ROOT_SIZE + ARM_TT_ROOT_INDEX_MASK) / 2ULL)) + 1ULL)</span></span></p><p><span style="font-family: 宋体;font-size: 14px;"><span style="font-family:Calibri;">static void</span></span></p><p><span style="font-family: 宋体;font-size: 14px;"><span style="font-family:Calibri;">arm_vm_kernel_el0_map(vm_offset_t vaddr, pt_entry_t pte)</span></span></p><p><span style="font-family: 宋体;font-size: 14px;"><span style="font-family:Calibri;">{</span></span></p><p><span style="font-family: 宋体;font-size: 14px;">        <span style="font-family:Calibri;">/* Calculate where vaddr will be in the EL1 kernel page tables. */</span></span></p><p><span style="font-family: 宋体;font-size: 14px;">        <span style="font-family:Calibri;">vm_offset_t kernel_pmap_vaddr = vaddr - ((ARM_TT_ROOT_INDEX_MASK + ARM_TT_ROOT_SIZE) / 2ULL);</span></span></p><p><span style="font-family: 宋体;font-size: 14px;">        <span style="font-family:Calibri;">arm_vm_map(</span></span><span style="font-family: 宋体;font-size: 14px;background: rgb(255, 255, 0);"><span style="font-family:Calibri;">cpu_tte</span></span><span style="font-family: 宋体;font-size: 14px;"><span style="font-family:Calibri;">, kernel_pmap_vaddr, pte);</span></span></p><p><span style="font-family: 宋体;font-size: 14px;"><span style="font-family:Calibri;">}</span></span></p><p style="text-indent: 28px;"><span style="font-family: 宋体;font-size: 14px;"><span style="font-family:宋体;">注意看</span><span style="font-family:Calibri;">arm_vm_map</span><span style="font-family:宋体;">的第一个参数为</span><span style="font-family:Calibri;">cpu_tte</span><span style="font-family:宋体;">，也就是内核的页表地址，</span><span style="font-family:Calibri;">XNU</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">KPTI</span><span style="font-family:宋体;">使用了内核页表中的一个表项，没有像</span><span style="font-family:Calibri;">linux</span><span style="font-family:宋体;">定义了一个全新的页表。所以不在需要切换</span><span style="font-family:Calibri;">vbar_el1</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">ttbr1_el1</span><span style="font-family:宋体;">寄存器，性能相比</span><span style="font-family:Calibri;">linux</span><span style="font-family:宋体;">会提升很多。</span></span></p>



<p><a href="2247483769">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=3ae01705&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg4NjU1NDU4MA%3D%3D%26mid%3D2247483769%26idx%3D1%26sn%3D3f6fae0b609addcd9b0aa5c736eef0e0%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Mon, 29 Nov 2021 14:08:00 +0800</pubDate>
    </item>
    <item>
      <title>IOS KTRR/CTRR详解</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg4NjU1NDU4MA==&amp;mid=2247483764&amp;idx=1&amp;sn=1aad5274320ba988861761c9f0b7a30d</link>
      <description>IOS KTRR/CTRR详解</description>
      <content:encoded><![CDATA[<p>
原创 <span>wzt</span> <span>2021-11-27 15:30</span> <span style="display: inline-block;"></span>
</p>

<p>IOS KTRR/CTRR详解</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=08a0b156&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F4iaJia7Cvd3PDNAAnmicGfP37JOPCWnFfIZqE8M7D2ykV8nWQtf8picibyzdN0m2tCq4BeJtak64cicKQkWAMrglbIYg%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<p><span style="font-size: 16px;"><span style="font-family: 宋体;font-size: 29px;">1.<span style="font-weight: bold;font-family: Calibri;">bootstrap_pagetables页表重写</span></span></span><br/></p><h1><strong><span style="font-family:宋体;font-size:29px;"><span style="font-family:宋体;"></span></span></strong></h1><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">之前内核启动时设置的临时页表</span><span style="font-family:Calibri;">_bootstrap_pagetables, </span><span style="font-family:宋体;">为了方便使用的是</span><span style="font-family:Calibri;">block</span><span style="font-family:宋体;">类型的映射，</span><span style="font-family:Calibri;">block</span><span style="font-family:宋体;">映射涵盖的虚拟地址范围非常大，后面对它的映射可能会被</span><span style="font-family:Calibri;">ktrr</span><span style="font-family:宋体;">拦截下来，所以需要更改下</span><span style="font-family:Calibri;">_bootstrap_pagetables</span><span style="font-family:宋体;">的页表，改为</span><span style="font-family:Calibri;">table</span><span style="font-family:宋体;">类型，同时</span><span style="font-family:Calibri;">_bootstrap_pagetables</span><span style="font-family:宋体;">需要用到的代码地址映射范围只需要到开启</span><span style="font-family:Calibri;">mmu</span><span style="font-family:宋体;">为止就可以。这个地址可以通过</span><span style="font-family:Calibri;">_bootstrap_instructions</span><span style="font-family:宋体;">符号来定位。</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">_arm_vm_init</span></span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">:</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">ADRL            X8, _bootstrap_instructions</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">AND             X21, X8, #0xFFFFFFFFFFFFC000</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             X0, X21</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">BL              _mmu_kvtop</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             X20, X0</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">计算出</span><span style="font-family:Calibri;">_bootstrap_instructions</span><span style="font-family:宋体;">的虚拟地址和物理地址。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">ADRL            X0, _bootstrap_pagetables ; l1 table</span></p><p><span style="font-family:Calibri;font-size:14px;">BL              _mmu_kvtop</span></p><p><span style="font-family:Calibri;font-size:14px;">CBNZ            X0, loc_FFFFFFF007B69070</span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;">_bootstrap_pagetables</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">为</span><span style="font-family:Calibri;">l1 table</span><span style="font-family:宋体;">地址。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X21, X0 ;</span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"> l1 table</span></p><p><span style="font-family:Calibri;font-size:14px;">UBFX            X19, X20, #0x24, #3 ; &#39;$&#39; ; </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">l1 index</span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X8, [X0,X19,LSL#3] ; </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">l1 pte</span></p><p><span style="font-family:Calibri;font-size:14px;">AND             X24, X8, #0xFFFFFFFFF000</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X0, X24 ; l2 table paddr</span></p><p><span style="font-family:Calibri;font-size:14px;">BL              _phystokv</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X22, X0 ;</span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"> l2 table vaddr</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">提取</span><span style="font-family:Calibri;">l1 index,pte</span><span style="font-family:宋体;">以及</span><span style="font-family:Calibri;">l2 table</span><span style="font-family:宋体;">虚拟地址。</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">ADRP            X9, #_ropage_next@PAGE</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">LDR             X23, [X9,#_ropage_next@PAGEOFF]</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">CBNZ            X23, loc_FFFFFFF007B690AC ; </span></span><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:Calibri;">l2 index</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">ADRL            X23, _ropagetable_begin</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">STR             X23, [X9,#_ropage_next@PAGEOFF]</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">UBFX            X26, X20, #0x19, #0xB ;</span></span><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"> <span style="font-family:Calibri;">l2 index</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">ADD             X8, X23, #4,LSL#12</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">STR             X8, [X9,#_ropage_next@PAGEOFF] ; </span></span><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:Calibri;">_ropage_next += 4096</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             X0, X23</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">BL              _mmu_kvtop</span></span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X25, X0 ; </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">new l3 table</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">提取</span><span style="font-family:Calibri;">l2 index</span><span style="font-family:宋体;">以及从</span><span style="font-family:Calibri;">_ropage_next </span><span style="font-family:宋体;">分配一个物理页作为</span><span style="font-family:Calibri;">l3 table</span><span style="font-family:宋体;">。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">UBFX            X27, X20, #0xE, #0xB ; l3 index</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">提取</span><span style="font-family:Calibri;">l3 index</span><span style="font-family:宋体;">。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X0, X21 ; void *</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W1, #0x4000 ; size_t</span></p><p><span style="font-family:Calibri;font-size:14px;">BL              _bzero  ; clear l1 talbe</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">清空</span><span style="font-family:Calibri;">l1table</span><span style="font-family:宋体;">所有页表项内容。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">ORR             X8, X24, #3</span></p><p><span style="font-family:Calibri;font-size:14px;">STR             X8, [X21,X19,LSL#3] ;</span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"> reset l1 pte with 0x3(table &amp; vaild)</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">然后重新设置</span><span style="font-family:Calibri;">_bootstrap_instructions</span><span style="font-family:宋体;">对应的</span><span style="font-family:Calibri;">l1 pte</span><span style="font-family:宋体;">，属性改为</span><span style="font-family:Calibri;">table</span><span style="font-family:宋体;">类型。</span></span></p><p><span style="font-family:Calibri;font-size:14px;"> MOV             X0, X22 ; void *</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W1, #0x4000 ; size_t</span></p><p><span style="font-family:Calibri;font-size:14px;">BL              _bzero  ; </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">clear l2 table</span></p><p><span style="font-family:Calibri;font-size:14px;">AND             X8, X25, #0xFFFFFFFFF000</span></p><p><span style="font-family:Calibri;font-size:14px;">ORR             X8, X8, #3</span></p><p><span style="font-family:Calibri;font-size:14px;">STR             X8, [X22,X26,LSL#3] ; </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">reset l2 talbe pte</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">清空</span><span style="font-family:Calibri;">l2 table</span><span style="font-family:宋体;">所有页表项，然后重新设置</span><span style="font-family:Calibri;">_bootstrap_instructions</span><span style="font-family:宋体;">对应的</span><span style="font-family:Calibri;">l2 pte</span><span style="font-family:宋体;">，属性改为</span><span style="font-family:Calibri;">table</span><span style="font-family:宋体;">类型。</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">AND             X8, X20, #0xFFFFFFFFC000</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             X9, #0x40000000000683</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">ORR             X8, X8, X9</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">STR             X8, [X23,X27,LSL#3] ; </span></span><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:Calibri;">setup l3 pte</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">重新设置</span><span style="font-family:Calibri;">_bootstrap_instructions</span><span style="font-family:宋体;">对应的</span><span style="font-family:Calibri;">l3 pte</span><span style="font-family:宋体;">，至此</span></span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">_bootstrap_pagetables</span><span style="font-family:宋体;">已经重新初始化完毕，不在受</span><span style="font-family:Calibri;">ktrr</span><span style="font-family:宋体;">影响了。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h1><span style="font-family:宋体;font-size:29px;">2. </span><strong><span style="font-family:宋体;font-size:29px;"><span style="font-family:宋体;">对</span><span style="font-family:Calibri;">devicetree</span><span style="font-family:宋体;">内存属性的改动</span></span></strong></h1><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">通常来讲，对</span><span style="font-family:Calibri;">ktrr/ctrr</span><span style="font-family:宋体;">的锁定是在</span><span style="font-family:Calibri;">devicetree</span><span style="font-family:宋体;">加载和引用结束后才实施的，但也可能在</span><span style="font-family:Calibri;">ktrr/ctrr</span><span style="font-family:宋体;">锁定后，也有对</span><span style="font-family:Calibri;">devicetree</span><span style="font-family:宋体;">的引用。因此在内核启动阶段对各个内核数据段进行权限设置时，也要把</span><span style="font-family:Calibri;">devicetree</span><span style="font-family:宋体;">所在的区域加入到</span><span style="font-family:Calibri;">ktrr/ctrr</span><span style="font-family:宋体;">的保护区域。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">_arm_vm_prot_init</span><span style="font-family:宋体;font-size:14px;">：</span></p><p><span style="font-family:Calibri;font-size:14px;">ADRP            X21, #_segPRELINKTEXTB@PAGE</span></p><p><span style="font-family:Calibri;font-size:14px;">STR             X8, [X24,#_segEXTRADATA@PAGEOFF]</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">起初</span><span style="font-family:Calibri;font-size:14px;">_segEXTRADATA</span><span style="font-family:宋体;font-size:14px;">保存的是</span><span style="font-family:Calibri;font-size:14px;">_segPRELINKTEXTB</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">地址，这是</span><span style="font-family:Calibri;">kernelcache</span><span style="font-family:宋体;">的最低地址。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">BL              _SecureDTIsLockedDown</span></p><p><span style="font-family:Calibri;font-size:14px;">CBZ             W0, loc_FFFFFFF007B68054</span></p><p><span style="font-family:Calibri;font-size:14px;">ADRL            X8, _PE_state.deviceTreeHead</span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X9, [X8]</span></p><p><span style="font-family:Calibri;font-size:14px;">STR             X9, [X24,#_segEXTRADATA@PAGEOFF]</span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X8, [X8,#(qword_FFFFFFF00772C240 - 0xFFFFFFF00772C230)]</span></p><p><span style="font-family:Calibri;font-size:14px;">STR             X8, [X25,#_segSizeEXTRADATA@PAGEOFF]</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">调用</span><span style="font-family:Calibri;font-size:14px;">_SecureDTIsLockedDown</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">，如果返回</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">，代表</span><span style="font-family:Calibri;">devicetree</span><span style="font-family:宋体;">的加载地址不包含在</span></span><span style="font-family:Calibri;font-size:14px;">_segPRELINKTEXTB</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">内，因此要把</span><span style="font-family:Calibri;">devicetree</span><span style="font-family:宋体;">的加载地址重新写入</span></span><span style="font-family:Calibri;font-size:14px;">segEXTRADATA</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">，然后在调用</span><span style="font-family:Calibri;">_arm_vm_page_granular_prot</span><span style="font-family:宋体;">做属性调整。</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">_SecureDTIsLockedDown</span><span style="font-family:宋体;">：</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">ADRL            X20, __mh_execute_header</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">ADRP            X8, #_DTRootNode@PAGE</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">LDR             X20, [X8,#_DTRootNode@PAGEOFF]</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">CMP             X8, #0</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">判断</span><span style="font-family:Calibri;">_DTRootNode</span><span style="font-family:宋体;">地址是否小于</span><span style="font-family:Calibri;">__mh_execute_header</span><span style="font-family:宋体;">。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h1 style="margin-left:0;text-indent:0;"><span style="font-family:宋体;font-size:29px;">3. </span><strong><span style="font-family:宋体;font-size:29px;">对</span></strong><strong><span style="font-family:Calibri;font-size:29px;">_update_mdscr</span></strong><strong><span style="font-family:宋体;font-size:29px;">的保护</span></strong></h1><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">mdscr</span><span style="font-family:宋体;">寄存器是</span><span style="font-family:Calibri;">arm</span><span style="font-family:宋体;">调试机制的控制寄存器，开启调试机制可能会绕过</span><span style="font-family:Calibri;">ktrr</span><span style="font-family:宋体;">保护，</span><span style="font-family:Calibri;">xnu</span><span style="font-family:宋体;">的一个缓解措施是在设置完</span><span style="font-family:Calibri;">mdscr</span><span style="font-family:宋体;">后，判断</span><span style="font-family:Calibri;">kde</span><span style="font-family:宋体;">位是否开启，如果开启就</span><span style="font-family:Calibri;">panic</span><span style="font-family:宋体;">。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">__TEXT_EXEC:__text:FFFFFFF008139478 _update_mdscr</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">:</span></span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X4, #0</span></p><p><span style="font-family:Calibri;font-size:14px;">MRS             X2, #0, c0, c2, #2</span></p><p><span style="font-family:Calibri;font-size:14px;">BIC             X2, X2, X0</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">X0</span><span style="font-family:宋体;">保存的是要清楚的</span><span style="font-family:Calibri;">bit</span><span style="font-family:宋体;">位。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">ORR             X2, X2, X1</span></p><p><span style="font-family:Calibri;font-size:14px;">AND             X2, X2, #0xFFFFFFFFFFFFDFFF</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #0, c0, c2, #2, X2</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">X1</span><span style="font-family:宋体;">保存的是要设置的</span><span style="font-family:Calibri;">bit</span><span style="font-family:宋体;">位。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">ANDS            X3, X2, #0x2000</span></p><p><span style="font-family:Calibri;font-size:14px;">ORR             X4, X4, X3</span></p><p><span style="font-family:Calibri;font-size:14px;">B.NE            loc_FFFFFFF008139488</span></p><p><span style="font-family:Calibri;font-size:14px;">CMP             X4, XZR</span></p><p><span style="font-family:Calibri;font-size:14px;">B.NE            loc_FFFFFFF0081394A8</span></p><p><span style="font-family:Calibri;font-size:14px;">RET</span></p><p><span style="font-family:Calibri;font-size:14px;">__TEXT_EXEC:__text:FFFFFFF0081394A8</span></p><p><span style="font-family:Calibri;font-size:14px;">ADRL            X0, aMdscrKdeWasSet ; &#34;MDSCR.KDE was set&#34;</span></p><p><span style="font-family:Calibri;font-size:14px;">B               _panic</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">判断</span><span style="font-family:Calibri;">kde</span><span style="font-family:宋体;">位是否开启，如果开启就</span><span style="font-family:Calibri;">panic</span><span style="font-family:宋体;">。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h1 style="margin-left:0;text-indent:0;"><span style="font-family:宋体;font-size:29px;">4. </span><strong><span style="font-family:宋体;font-size:29px;"><span style="font-family:Calibri;">Ktrr/ctrr</span><span style="font-family:宋体;">锁定</span></span></strong></h1><p><span style="font-family:Calibri;font-size:14px;">_kernel_bootstrap</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">-&gt;_machine_init-&gt;_rorgn_stash_range</span></span></p><p><span style="font-family:Calibri;font-size:14px;">_rorgn_stash_range</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">:</span></span></p><p><span style="font-family:Calibri;font-size:14px;">ADRP            X8, #_segLOWESTRO@PAGE</span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X19, [X8,#_segLOWESTRO@PAGEOFF]</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X0, X19</span></p><p><span style="font-family:Calibri;font-size:14px;">BL              _mmu_kvtop</span></p><p><span style="font-family:Calibri;font-size:14px;">CBNZ            X0, loc_FFFFFFF007B624E8</span></p><p><span style="font-family:Calibri;font-size:14px;">loc_FFFFFFF007B624E8                    ; CODE XREF: _rorgn_stash_range+1D8↑j</span></p><p><span style="font-family:Calibri;font-size:14px;">ADRP            X8, #_ctrr_begin@PAGE</span></p><p><span style="font-family:Calibri;font-size:14px;">STR             X0, [X8,#_ctrr_begin@PAGEOFF]</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">将</span><span style="font-family:Calibri;font-size:14px;">_segLOWESTRO</span><span style="font-family:宋体;font-size:14px;">地址写入</span><span style="font-family:Calibri;font-size:14px;">_ctrr_begin</span></p><p><span style="font-family:Calibri;font-size:14px;">ADRP            X8, #_segHIGHESTRO@PAGE</span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X19, [X8,#_segHIGHESTRO@PAGEOFF]</span></p><p><span style="font-family:Calibri;font-size:14px;">CBZ             X19, loc_FFFFFFF007B6252C</span></p><p><span style="font-family:Calibri;font-size:14px;">SUB             X8, X0, #1</span></p><p><span style="font-family:Calibri;font-size:14px;">ADRP            X9, #_ctrr_end@PAGE</span></p><p><span style="font-family:Calibri;font-size:14px;">STR             X8, [X9,#_ctrr_end@PAGEOFF]</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">如果</span><span style="font-family:Calibri;">kernelcache binary</span><span style="font-family:宋体;">存在</span></span><span style="font-family:Calibri;font-size:14px;">_segHIGHESTRO</span><span style="font-family:宋体;font-size:14px;">，则将</span><span style="font-family:Calibri;font-size:14px;">_segHIGHESTRO</span><span style="font-family:宋体;font-size:14px;"> <span style="font-family:Calibri;">- 1</span><span style="font-family:宋体;">存入</span></span><span style="font-family:Calibri;font-size:14px;">_ctrr_end</span><span style="font-family:宋体;font-size:14px;">。</span></p><p><span style="font-family:Calibri;font-size:14px;">loc_FFFFFFF007B6252C                    ; CODE XREF: _rorgn_stash_range+20C↑j</span></p><p><span style="font-family:Calibri;font-size:14px;">ADRP            X8, #_segLASTB@PAGE</span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X19, [X8,#_segLASTB@PAGEOFF]</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X0, X19</span></p><p><span style="font-family:Calibri;font-size:14px;">ADRP            X8, #_segSizeLAST@PAGE</span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X8, [X8,#_segSizeLAST@PAGEOFF]</span></p><p><span style="font-family:Calibri;font-size:14px;">ADD             X0, X8, X0</span></p><p><span style="font-family:Calibri;font-size:14px;">SUB             X8, X0, #1</span></p><p><span style="font-family:Calibri;font-size:14px;">ADRP            X9, #_ctrr_end@PAGE</span></p><p><span style="font-family:Calibri;font-size:14px;">STR             X8, [X9,#_ctrr_end@PAGEOFF]</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">如果</span><span style="font-family:Calibri;">kernelcache binary</span><span style="font-family:宋体;">不存在</span></span><span style="font-family:Calibri;font-size:14px;">_segHIGHESTRO</span><span style="font-family:宋体;font-size:14px;">，则将</span><span style="font-family:Calibri;font-size:14px;">_segLASTB</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">+</span></span><span style="font-family:Calibri;font-size:14px;">segSizeLAST</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">-1</span><span style="font-family:宋体;">写入</span></span><span style="font-family:Calibri;font-size:14px;">_ctrr_end</span><span style="font-family:宋体;font-size:14px;">。</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">_rorgn_stash_range</span><span style="font-family:宋体;">函数只是计算出了</span></span><span style="font-family:Calibri;font-size:14px;">_ctrr_begin</span><span style="font-family:宋体;font-size:14px;">和</span><span style="font-family:Calibri;font-size:14px;">_ctrr_end</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">，真正对内核锁定是在</span><span style="font-family:Calibri;">_rorgn_lockdown</span><span style="font-family:宋体;">函数。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">_kernel_bootstrap_thread</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">-&gt;</span></span><span style="font-family:Calibri;font-size:14px;">_machine_lockdown</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">-&gt;_rorgn_lockdown</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">_rorgn_lockdown</span><span style="font-family:宋体;">：</span></span></p><p><span style="font-family:Calibri;font-size:14px;">ADRP            X9, #_ctrr_begin@PAGE</span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X9, [X9,#_ctrr_begin@PAGEOFF]</span></p><p><span style="font-family:Calibri;font-size:14px;">ADRP            X10, #_ctrr_end@PAGE</span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X10, [X10,#_ctrr_end@PAGEOFF]</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #4, c15, c2, #3, X9 ; S3_4_C15_C2_3</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #4, c15, c2, #4, X10 ; S3_4_C15_C2_4</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W11, #0x12</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #4, c15, c2, #5, X11 ; S3_4_C15_C2_5</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W11, #1</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #4, c15, c2, #2, X11 ; S3_4_C15_C2_2</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">将</span><span style="font-family:Calibri;font-size:14px;">_ctrr_begin</span><span style="font-family:宋体;font-size:14px;">写入</span><span style="font-family:Calibri;font-size:14px;">S3_4_C15_C2_3</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">寄存器，它保存的是</span><span style="font-family:Calibri;">ctrr</span><span style="font-family:宋体;">保护的起始地址，将</span></span><span style="font-family:Calibri;font-size:14px;">_ctrr_end</span><span style="font-family:宋体;font-size:14px;">写入</span><span style="font-family:Calibri;font-size:14px;">S3_4_C15_C2_4</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">，它保存的是</span><span style="font-family:Calibri;">ctrr</span><span style="font-family:宋体;">保护的结束地址。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">将</span><span style="font-family:Calibri;">0x12</span><span style="font-family:宋体;">写入</span></span><span style="font-family:Calibri;font-size:14px;">S3_4_C15_C2_5</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">寄存器，它保存的是</span><span style="font-family:Calibri;">ctrr</span><span style="font-family:宋体;">的控制状态。</span><span style="font-family:Calibri;">Xnu source code</span><span style="font-family:宋体;">里已经有对它的描述：</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">Apple_arm64_regs.h</span></span></p><p><span style="font-family:Calibri;font-size:14px;">#define CTRR_CTL_EL1_A_MMUOFF_WRPROTECT  (1 &lt;&lt; 0)</span></p><p><span style="font-family:Calibri;font-size:14px;">#define CTRR_CTL_EL1_A_MMUON_WRPROTECT   (1 &lt;&lt; 1)</span></p><p><span style="font-family:Calibri;font-size:14px;">#define CTRR_CTL_EL1_B_MMUOFF_WRPROTECT  (1 &lt;&lt; 2)</span></p><p><span style="font-family:Calibri;font-size:14px;">#define CTRR_CTL_EL1_B_MMUON_WRPROTECT   (1 &lt;&lt; 3)</span></p><p><span style="font-family:Calibri;font-size:14px;">#define CTRR_CTL_EL1_A_PXN               (1 &lt;&lt; 4)</span></p><p><span style="font-family:Calibri;font-size:14px;">#define CTRR_CTL_EL1_B_PXN               (1 &lt;&lt; 5)</span></p><p><span style="font-family:Calibri;font-size:14px;">#define CTRR_CTL_EL1_A_UXN               (1 &lt;&lt; 6)</span></p><p><span style="font-family:Calibri;font-size:14px;">#define CTRR_CTL_EL1_B_UXN               (1 &lt;&lt; 7)</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">将</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">写入</span></span><span style="font-family:Calibri;font-size:14px;">S3_4_C15_C2_2</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">寄存器，锁定</span><span style="font-family:Calibri;">ctrr</span><span style="font-family:宋体;">。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">MRS             X11, #0, c4, c2, #2 ; CurrentEL</span></p><p><span style="font-family:Calibri;font-size:14px;">CMP             X11, #8 ; el2</span></p><p><span style="font-family:Calibri;font-size:14px;">B.NE            loc_FFFFFFF007B62DEC</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #4, c15, c11, #0, X9 ; S3_4_C15_C11_0</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #4, c15, c11, #1, X10 ; S3_4_C15_C11_1</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W9, #0x12</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #4, c15, c11, #4, X9 ; S3_4_C15_C11_4</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W9, #1</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #4, c15, c11, #5, X9 ; S3_4_C15_C11_5</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">可以看到</span><span style="font-family:Calibri;">ctrr</span><span style="font-family:宋体;">除了能对</span><span style="font-family:Calibri;">el1</span><span style="font-family:宋体;">内核代码做保护，还可以对</span><span style="font-family:Calibri;">el2 hypervisor</span><span style="font-family:宋体;">做保护。</span></span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;">S3_4_C15_C11_0</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">代表要保存的</span><span style="font-family:Calibri;">el2</span><span style="font-family:宋体;">代码起始地址，</span></span><span style="font-family:Calibri;font-size:14px;">S3_4_C15_C11_1</span><span style="font-family:宋体;font-size:14px;">代表结束地址，</span><span style="font-family:Calibri;font-size:14px;">S3_4_C15_C11_4</span><span style="font-family:宋体;font-size:14px;">代表控制寄存器，</span><span style="font-family:Calibri;font-size:14px;">S3_4_C15_C11_5</span><span style="font-family:宋体;font-size:14px;">代表锁定寄存器。</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">Ktrr/ctrr</span><span style="font-family:宋体;">保护的区域范围如下：</span></span></p><p><span style="font-family:宋体;font-size:14px;"> <span style="font-family:Calibri;">* __PRELINK_TEXT    &lt;--- First KTRR (ReadOnly) segment</span></span></p><p><span style="font-family:宋体;font-size:14px;"> <span style="font-family:Calibri;">* __PLK_DATA_CONST</span></span></p><p><span style="font-family:宋体;font-size:14px;"> <span style="font-family:Calibri;">* __PLK_TEXT_EXEC</span></span></p><p><span style="font-family:宋体;font-size:14px;"> <span style="font-family:Calibri;">* __TEXT</span></span></p><p><span style="font-family:宋体;font-size:14px;"> <span style="font-family:Calibri;">* __DATA_CONST</span></span></p><p><span style="font-family:宋体;font-size:14px;"> <span style="font-family:Calibri;">* __TEXT_EXEC</span></span></p><p><span style="font-family:宋体;font-size:14px;"> <span style="font-family:Calibri;">* __KLD</span></span></p><p><span style="font-family:宋体;font-size:14px;"> <span style="font-family:Calibri;">* __LAST            &lt;--- Last KTRR (ReadOnly) segment</span></span></p><p><span style="font-family:宋体;font-size:14px;"> <span style="font-family:Calibri;">* __DATA</span></span></p><p><span style="font-family:宋体;font-size:14px;"> <span style="font-family:Calibri;">* __BOOTDATA (if present)</span></span></p><p><span style="font-family:宋体;font-size:14px;"> <span style="font-family:Calibri;">* __LINKEDIT</span></span></p><p><span style="font-family:宋体;font-size:14px;"> <span style="font-family:Calibri;">* __PRELINK_DATA (expected populated now)</span></span></p><p><span style="font-family:宋体;font-size:14px;"> <span style="font-family:Calibri;">* __PLK_LINKEDIT</span></span></p><p><span style="font-family:宋体;font-size:14px;"> <span style="font-family:Calibri;">* __PRELINK_INFO</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;"><br/></span></span></p><h1><span style="font-family:Calibri;font-size:29px;">5. </span><strong><span style="font-family:Calibri;font-size:29px;">_reset_vector</span></strong><strong><span style="font-family:宋体;font-size:29px;">的行为</span></strong></h1><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">系统重启后的第一件事就是锁定</span><span style="font-family:Calibri;">ktrr/ctrr</span><span style="font-family:宋体;">寄存器。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">_reset_vector</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">:</span></span></p><p><span style="font-family:Calibri;font-size:14px;"> ADRL            X17, _ctrr_begin</span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X17, [X17]</span></p><p><span style="font-family:Calibri;font-size:14px;">CBZ             X17, loc_FFFFFFF00813445C</span></p><p><span style="font-family:Calibri;font-size:14px;">ADRL            X19, _ctrr_end</span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X19, [X19]</span></p><p><span style="font-family:Calibri;font-size:14px;">CBZ             X19, loc_FFFFFFF00813446C</span></p><p><span style="font-family:Calibri;font-size:14px;">MRS             X18, #4, c15, c2, #2</span></p><p><span style="font-family:Calibri;font-size:14px;">CBNZ            X18, loc_FFFFFFF0081344A8</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #4, c15, c2, #3, X17 ; S3_4_C15_C2_3</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #4, c15, c2, #4, X19 ; S3_4_C15_C2_4</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X18, #0x12</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #4, c15, c2, #5, X18 ; S3_4_C15_C2_5</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X18, #1</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #4, c15, c2, #2, X18 ; S3_4_C15_C2_2</span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p>



<p><a href="2247483764">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=43e03fdb&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg4NjU1NDU4MA%3D%3D%26mid%3D2247483764%26idx%3D1%26sn%3D1aad5274320ba988861761c9f0b7a30d%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Sat, 27 Nov 2021 15:30:00 +0800</pubDate>
    </item>
    <item>
      <title>IOS PPL实现详解</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg4NjU1NDU4MA==&amp;mid=2247483759&amp;idx=1&amp;sn=766e80eef7692c896c6cbae7c6776981</link>
      <description>ios ppl实现详解</description>
      <content:encoded><![CDATA[<p>
原创 <span>wzt</span> <span>2021-11-26 11:29</span> <span style="display: inline-block;"></span>
</p>

<p>ios ppl实现详解</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=442bd95c&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F4iaJia7Cvd3PCUNWThdNcFzsbyAuM3eyKVmHicMlUPwMWRFicXdceiaxHYo6ibxjbTnjbI64y56lxYJ95Y7GhM9NXJMQ%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<p><span style="font-family: 宋体;font-size: 29px;">1. </span><strong style="font-size: 16px;"><span style="font-family:宋体;font-size:29px;"><span style="font-family:Calibri;">Ppl</span>代码初始化</span></strong><br/></p><h1><strong><span style="font-family:宋体;font-size:29px;"><span style="font-family:宋体;"></span></span></strong></h1><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">1.1 ppl</span><span style="font-family:黑体;">物理内存初始化</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">内核在启动阶段调用</span><span style="font-family:Calibri;">pmap_bootstrap</span><span style="font-family:宋体;">函数初始化物理内存布局。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">pmap_bootstrap</span><span style="font-family:宋体;font-size:14px;">：</span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">LDR             X20, [X27,#_avail_start@PAGEOFF]</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             X0, X20</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">BL              _phystokv</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             X21, X0</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">ADRP            X8, #_pmap_array_begin@PAGE</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">STR             X0, [X8,#_pmap_array_begin@PAGEOFF]</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">ADRP            X19, #_pmap_array@PAGE</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">STR             X0, [X19,#_pmap_array@PAGEOFF]</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">ADRP            X24, #_pmap_max_asids@PAGE</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">LDR             W8, [X24,#_pmap_max_asids@PAGEOFF]</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             W9, #0x108</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             W10, #0x3FFF</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MADD            X8, X8, X9, X10</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">AND             X8, X8, #0x3FFFFFFC000</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">ADD             X0, X8, X20</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">STR             X0, [X27,#_avail_start@PAGEOFF]</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">BL              _phystokv</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">ADRP            X8, #_pmap_array_end@PAGE</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">STR             X0, [X8,#_pmap_array_end@PAGEOFF]</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">_avail_start</span><span style="font-family:宋体;">保存的是当前空闲物理内存的物理地址，转换成虚拟地址后，保存在</span><span style="font-family:Calibri;">_pmap_array_begin</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">_pmap_array</span><span style="font-family:宋体;">变量中，然后从此物理地址划出</span><span style="font-family:Calibri;">_pmap_max_asids</span><span style="font-family:宋体;">字节大小的区域给</span><span style="font-family:Calibri;">_pmap_array</span><span style="font-family:宋体;">，它是一个</span><span style="font-family:Calibri;">struct pmap</span><span style="font-family:宋体;">数组，在</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">的实现中，内核以及每个进程都有单独的一个</span><span style="font-family:Calibri;">struct pmap</span><span style="font-family:宋体;">结构。在非</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">的版本中，只有内核使用</span><span style="font-family:Calibri;">struct map</span><span style="font-family:宋体;">。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">ADRP            X8, #_pmap_array_count@PAGE</span></p><p><span style="font-family:Calibri;font-size:14px;">ADRL            X10, _pmap_free_list_lock</span></p><p><span style="font-family:Calibri;font-size:14px;">STR             X9, [X8,#_pmap_array_count@PAGEOFF]</span></p><p><span style="font-family:Calibri;font-size:14px;">STR             X23, [X10,#(qword_FFFFFFF00981CA88 - 0xFFFFFFF00981CA80)]</span></p><p><span style="font-family:Calibri;font-size:14px;">STR             XZR, [X10]</span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X9, [X8,#_pmap_array_count@PAGEOFF]</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">计算</span><span style="font-family:Calibri;font-size:14px;">_pmap_array_count</span><span style="font-family:宋体;font-size:14px;">大小。</span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             X9, #0</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             X10, #0</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             X12, #0</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">LDR             X11, [X19,#_pmap_array@PAGEOFF]</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">STR             X12, [X11,X9]</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">LDR             X11, [X19,#_pmap_array@PAGEOFF]</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">ADD             X12, X11, X9</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">ADD             X10, X10, #1</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">LDR             X13, [X8,#_pmap_array_count@PAGEOFF]</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">ADD             X9, X9, #0x108</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">CMP             X10, X13</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">B.CC            loc_FFFFFFF007B5E820</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">ADD             X8, X11, X9</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">SUB             X8, X8, #0x108</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">B               loc_FFFFFFF007B5E850</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             X8, #0</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">ADRP            X9, #_pmap_free_list@PAGE</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">STR             X8, [X9,#_pmap_free_list@PAGEOFF]</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">初始化</span><span style="font-family:Calibri;">_pmap_free_list</span><span style="font-family:宋体;">链表，循环让</span><span style="font-family:Calibri;">_pmap_array</span><span style="font-family:宋体;">数组中的每个元素依次指向前一个节点，以后</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">为每个进程分配</span><span style="font-family:Calibri;">struct pmap</span><span style="font-family:宋体;">结构体时就从这个链表分配。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">下面用类似的算法初始化</span><span style="font-family:Calibri;">_pmap_ledger_ptr_array</span><span style="font-family:宋体;">数组，这里不在赘述。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">然后开始初始化</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">使用的</span><span style="font-family:Calibri;">stack</span><span style="font-family:宋体;">信息：</span></span></p><p><span style="font-family:Calibri;font-size:14px;">ADRP            X8, #_pmap_stacks_start@PAGE</span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X8, [X8,#_pmap_stacks_start@PAGEOFF]</span></p><p><span style="font-family:Calibri;font-size:14px;">ADD             X26, X8, #4,LSL#12</span></p><p><span style="font-family:Calibri;font-size:14px;">ADRP            X8, #_pmap_stacks_start_pa@PAGE</span></p><p><span style="font-family:Calibri;font-size:14px;">STR             X20, [X8,#_pmap_stacks_start_pa@PAGEOFF]</span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;">_pmap_stacks_start</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">保存的是</span><span style="font-family:Calibri;">stack</span><span style="font-family:宋体;">的虚拟地址，</span></span><span style="font-family:Calibri;font-size:14px;">_pmap_stacks_start_pa</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">保存的是</span><span style="font-family:Calibri;">stack</span><span style="font-family:宋体;">的物理地址，后面修改</span><span style="font-family:Calibri;">kernel_map-&gt;tte</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">l3</span><span style="font-family:宋体;">页表，进行虚拟地址到物理地址的映射。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X28, #0x20000000000603</span></p><p><span style="font-family:Calibri;font-size:14px;">ADRL            X21, _pmap_cpu_data_array</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W25, #0xFFFFFFFF</span></p><p><span style="font-family:Calibri;font-size:14px;">B               loc_FFFFFFF007B5E92C</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W8, #0x180</span></p><p><span style="font-family:Calibri;font-size:14px;">MADD            X8, X19, X8, X21</span></p><p><span style="font-family:Calibri;font-size:14px;">STR             W25, [X8,#0x40]</span></p><p><span style="font-family:Calibri;font-size:14px;">STR             WZR, [X8,#0x18]</span></p><p><span style="font-family:Calibri;font-size:14px;">STR             X24, [X8,#8]</span></p><p><span style="font-family:Calibri;font-size:14px;">ADD             X26, X26, #8,LSL#12</span></p><p><span style="font-family:Calibri;font-size:14px;">ADD             X19, X19, #1</span></p><p><span style="font-family:Calibri;font-size:14px;">CMP             X19, #6</span></p><p><span style="font-family:Calibri;font-size:14px;">B.EQ            loc_FFFFFFF007B5E9B8</span></p><p><span style="font-family:Calibri;font-size:14px;">ADD             X24, X26, #4,LSL#12</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X23, X26</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X8, #0xFFFFFFFFFFFFBFFF</span></p><p><span style="font-family:Calibri;font-size:14px;">CMP             X26, X8</span></p><p><span style="font-family:Calibri;font-size:14px;">B. </span><span style="font-family:Calibri;font-size:14px;">HI            loc_FFFFFFF007B5E908</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">依次设置每个</span><span style="font-family:Calibri;">cpu</span><span style="font-family:宋体;">的</span></span><span style="font-family:Calibri;font-size:14px;"> _pmap_cpu_data</span><span style="font-family:宋体;font-size:14px;">结构体，</span><span style="font-family:Calibri;font-size:14px;">STR             X24, [X8,#8]</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">，将栈地址保存在</span><span style="font-family:Calibri;">0x8</span><span style="font-family:宋体;">偏移处。每个</span><span style="font-family:Calibri;">cpu</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">ppl stack</span><span style="font-family:宋体;">都是</span><span style="font-family:Calibri;">4k</span><span style="font-family:宋体;">，之间在隔离着一个</span><span style="font-family:Calibri;">4k</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">guard page</span><span style="font-family:宋体;">。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">后面的代码继续初始化</span><span style="font-family:Calibri;">_ppl_cpu_save_area</span><span style="font-family:宋体;">，它保存的是</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">进入</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">异常处理时保存的全部寄存器区域。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">下面给出</span><span style="font-family:Calibri;">xnu</span><span style="font-family:宋体;">物理内存布局图，请原谅我的懒惰，不想画漂亮的图形。</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.67421875" data-s="300,640" style="" data-type="jpeg" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=7c1a07f4&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F4iaJia7Cvd3PCUNWThdNcFzsbyAuM3eyKVh6nFicZeowLsYo9d01VOKic9ByZd1aiad5SibM0PHEMqiaibPaRpT3P5fMQA%2F640%3Fwx_fmt%3Djpeg"/></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"></span></span><br/></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">1.2 pp_attr_table</span><span style="font-family:黑体;">与</span><span style="font-family:Arial;">pv_head_table</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">XNU</span><span style="font-family:宋体;">的物理内存管理模型，增加了两个结构体用于辅助物理页的管理。</span></span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;">pp_attr_t</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">代表的是一个物理页的属性，在</span><span style="font-family:Calibri;">XNU</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">source code</span><span style="font-family:宋体;">里可以看到其定义：</span></span></p><p><span style="font-family:Calibri;font-size:14px;">osfmk/arm/pmap.c</span></p><p><span style="font-family:Calibri;font-size:14px;">typedef u_int16_t pp_attr_t;</span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">#define PP_ATTR_WIMG_MASK               0x003F</span></p><p><span style="font-family:Calibri;font-size:14px;">#define PP_ATTR_WIMG(x)                 ((x) &amp; PP_ATTR_WIMG_MASK)</span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">#define PP_ATTR_REFERENCED              0x0040</span></p><p><span style="font-family:Calibri;font-size:14px;">#define PP_ATTR_MODIFIED                0x0080</span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">#define PP_ATTR_INTERNAL                0x0100</span></p><p><span style="font-family:Calibri;font-size:14px;">#define PP_ATTR_REUSABLE                0x0200</span></p><p><span style="font-family:Calibri;font-size:14px;">#define PP_ATTR_ALTACCT                 0x0400</span></p><p><span style="font-family:Calibri;font-size:14px;">#define PP_ATTR_NOENCRYPT               0x0800</span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">#define PP_ATTR_REFFAULT                0x1000</span></p><p><span style="font-family:Calibri;font-size:14px;">#define PP_ATTR_MODFAULT                0x2000</span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">#if XNU_MONITOR</span></p><p><span style="font-family:Calibri;font-size:14px;">/*</span></p><p><span style="font-family:Calibri;font-size:14px;"> * Denotes that a page is owned by the PPL.  This is modified/checked with the</span></p><p><span style="font-family:Calibri;font-size:14px;"> * PVH lock held, to avoid ownership related races.  This does not need to be a</span></p><p><span style="font-family:Calibri;font-size:14px;"> * PP_ATTR bit (as we have the lock), but for now this is a convenient place to</span></p><p><span style="font-family:Calibri;font-size:14px;"> * put the bit.</span></p><p><span style="font-family:Calibri;font-size:14px;"> */</span></p><p><span style="font-family:Calibri;font-size:14px;">#define PP_ATTR_MONITOR                 0x4000</span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">/*</span></p><p><span style="font-family:Calibri;font-size:14px;"> * Denotes that a page *cannot* be owned by the PPL.  This is required in order</span></p><p><span style="font-family:Calibri;font-size:14px;"> * to temporarily &#39;pin&#39; kernel pages that are used to store PPL output parameters.</span></p><p><span style="font-family:Calibri;font-size:14px;"> * Otherwise a malicious or buggy caller could pass PPL-owned memory for these</span></p><p><span style="font-family:Calibri;font-size:14px;"> * parameters and in so doing stage a write gadget against the PPL.</span></p><p><span style="font-family:Calibri;font-size:14px;"> */</span></p><p><span style="font-family:Calibri;font-size:14px;">#define PP_ATTR_NO_MONITOR              0x8000</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">对于</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">来讲，增加了两个属性</span></span><span style="font-family:Calibri;font-size:14px;">PP_ATTR_MONITOR</span><span style="font-family:宋体;font-size:14px;">和</span><span style="font-family:Calibri;font-size:14px;">PP_ATTR_NO_MONITOR</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">，</span><span style="font-family:Calibri;">ios</span><span style="font-family:宋体;">使用相同的值，后面会看到。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">每个物理页在内核中有两种用处，第一个物理页保存的是页表内容，第二个就是保存内核用到的其他数据结构，在</span><span style="font-family:Calibri;">XNU</span><span style="font-family:宋体;">的物理内存管理模型中，使用</span><span style="font-family:Calibri;">struct pv_entry</span><span style="font-family:宋体;">结构体保存</span><span style="font-family:Calibri;">l3</span><span style="font-family:宋体;">页表项的地址，可以提高物理内存与虚拟内存相互转化的效率。使用</span><span style="font-family:Calibri;">struct pt_desc</span><span style="font-family:宋体;">结构体描述一个页表属性，比如</span><span style="font-family:Calibri;">l1</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">l2</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">l3table</span><span style="font-family:宋体;">的属性。对于</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">，会用到</span><span style="font-family:Calibri;">pv_head_table</span><span style="font-family:宋体;">对给定的一个物理页上锁。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">Pv_head_table</span><span style="font-family:宋体;">的内存布局如下，请再次原谅我的懒惰。</span></span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.67421875" data-s="300,640" style="" data-type="jpeg" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=fbded683&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F4iaJia7Cvd3PCUNWThdNcFzsbyAuM3eyKVPcAOFWxdZ8CicAXfw28WRsnz2UxpX8YPwzbgQ3wmxia7EiayWqImiaGwEQ%2F640%3Fwx_fmt%3Djpeg"/></p><p style="text-align: center;"><br/></p><p><span style="font-family:Calibri;font-size:14px;"></span><br/></p><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">1.3 EL1_Guard level</span><span style="font-family:黑体;">初始化</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">在初始化完</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">的物理内存布局后，内核在启动的下一阶段会调用</span></span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">_bootstrap_instructions</span></span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">继续执行</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">的初始化。</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">__start-&gt;_start_first_cpu-&gt;_arm_init-&gt;_arm_vm_init-&gt;_bootstrap_instructions</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">_bootstrap_instructions:</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">关闭</span><span style="font-family:Calibri;">mmu</span></span></p><p><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C1_0</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">0x1</span></span></p><p><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C1_1</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">0x1</span></span></p><p><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C1_5</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">0x2010000030100000</span></span></p><p><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C1_6</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">0x2020000030200000</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">S3_6_C15_C1_7</span></span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">0x2020a500f020f000</span></span></p><p><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C3_0</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">0x2020a505f020f0f0</span></span></p><p><span style="font-family:宋体;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C1_2</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">0x1</span></span></p><p><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C8_1</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">_gxf_bootstrap_handler(</span><span style="font-family:宋体;">虚拟地址</span><span style="font-family:Calibri;">)</span></span></p><p><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C8_2</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">_gtr_deadloop(</span><span style="font-family:宋体;">虚拟地址</span><span style="font-family:Calibri;">)</span></span></p><p><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C1_2</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">0x0</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">开启</span><span style="font-family:Calibri;">mmu</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">在这个函数里，可以看到苹果</span><span style="font-family:Calibri;">cpu</span><span style="font-family:宋体;">加入了几个新的系统寄存器， 通过分析代码逻辑可以推测出</span></span><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C1_2</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">寄存器应该是个执行上锁和解锁的功能。</span><span style="font-family:Calibri;">gxf_bootstrap_handler</span><span style="font-family:宋体;">函数地址存入了</span></span><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C8_1</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">寄存器，</span><span style="font-family:Calibri;">_gtr_deadloop</span><span style="font-family:宋体;">函数存入了</span></span><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C8_2</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">寄存器。在整个</span><span style="font-family:Calibri;">kernelcache</span><span style="font-family:宋体;">代码段里都没有搜索到对</span><span style="font-family:Calibri;">_gxf_bootstrap_handler</span><span style="font-family:宋体;">函数的直接引用，因此可以推断出</span></span><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C8_1</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">寄存器保存的地址应该是</span><span style="font-family:Calibri;">cpu</span><span style="font-family:宋体;">进入</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">时首先要执行的函数。在另外一个初始化路径中也可以看到相同的</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">初始化代码。</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">__start-&gt;_start_first_cpu-&gt;_arm_init-&gt;_cpu_machine_idle_init-&gt;_start_cpu-&gt;start_cpu</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">start_cpu</span></span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">:</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">S3_6_C15_C1_0</span></span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">0x1</span></span></p><p><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C1_1</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">0x1</span></span></p><p><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C3_0</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">0x2020a506f020f0e0</span></span></p><p><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C1_5</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">0x2010000030100000</span></span></p><p><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C1_6</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">0x2020000030200000</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">S3_6_C15_C1_7</span></span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">0x2020a500f020f000</span></span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C1_2</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">0x1</span></span></p><p><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C8_1</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">_gxf_bootstrap_handler(</span><span style="font-family:宋体;">虚拟地址</span><span style="font-family:Calibri;">)</span></span></p><p><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C8_2</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">_gtr_deadloop(</span><span style="font-family:宋体;">虚拟地址</span><span style="font-family:Calibri;">)</span></span></p><p><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C1_2</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">0x0</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">注意这两个初始化函数只是对</span><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C8_1</span><span style="font-family:宋体;font-size:14px;">寄存器进行了设置，并没有调用它。在内核启动的最后阶段有如下调用代码：</span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">_kernel_bootstrap_thread-&gt;machine_lockdown</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">ADRP            X8, #_pmap_ppl_locked_down@PAGE</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             W19, #1</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">STR             W19, [X8,#_pmap_ppl_locked_down@PAGEOFF]</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">BL              _gxf_enable</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">首先对</span><span style="font-family:Calibri;">_pmap_ppl_locked_down</span><span style="font-family:宋体;">变量设置为</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">，这个状态表示</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">已经初始化完毕，</span><span style="font-family:Calibri;">el1</span><span style="font-family:宋体;">代码可以向</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">请求服务了。然后调用</span><span style="font-family:Calibri;">_gxf_enable</span><span style="font-family:宋体;">：</span></span></p><p><span style="font-family:Calibri;font-size:14px;">_gxf_enable:</span></p><p><span style="font-family:Calibri;font-size:14px;">fffffff008131e90        mov     x0, #0x1</span></p><p><span style="font-family:Calibri;font-size:14px;">fffffff008131e94        msr     S3_6_C15_C1_2, x0</span></p><p><span style="font-family:Calibri;font-size:14px;">fffffff008131e98        .long   0x00201420</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">在对</span><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C1_2</span><span style="font-family:宋体;font-size:14px;">寄存器赋值后，出现了</span><span style="font-family:Calibri;font-size:14px;">0x00201420</span><span style="font-family:宋体;font-size:14px;">这个反汇编器无法识别的指令。那么这个有可能的两种情况，第一个假设</span><span style="font-family:Calibri;font-size:14px;">0x00201420</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">不是苹果</span><span style="font-family:Calibri;">cpu</span><span style="font-family:宋体;">的新增指令，那么当</span><span style="font-family:Calibri;">cpu</span><span style="font-family:宋体;">进行执行时，会产生</span><span style="font-family:Calibri;">exception</span><span style="font-family:宋体;">异常，历史上，</span><span style="font-family:Calibri;">PAX</span><span style="font-family:宋体;">团队曾经在异常处理代码里模拟了</span><span style="font-family:Calibri;">NX</span><span style="font-family:宋体;">在</span><span style="font-family:Calibri;">32</span><span style="font-family:宋体;">位处理器上的软件实现，但笔者翻遍了异常处理逻辑的所有代码，也没有发现对</span></span><span style="font-family:Calibri;font-size:14px;">0x00201420</span><span style="font-family:宋体;font-size:14px;">这个数据或指令的特殊处理，因此可以断定</span><span style="font-family:Calibri;font-size:14px;">0x00201420</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">是苹果</span><span style="font-family:Calibri;">cpu</span><span style="font-family:宋体;">新增的指令，在后面的</span><span style="font-family:Calibri;">reverse</span><span style="font-family:宋体;">中，可以发现它是进入</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">的指令，</span></span><span style="font-family:Calibri;font-size:14px;">0x002014</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">0</span></span><span style="font-family:Calibri;font-size:14px;">0</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">则是退出</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">的指令。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">在前面的分析中讲到</span><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C8_1</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">寄存器保存的地址是进入</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">时首先要执行的地址，在前面的初始化时被设置为了</span><span style="font-family:Calibri;">_gxf_bootstrap_handler</span><span style="font-family:宋体;">。</span></span></p><p><span style="font-family:Calibri;font-size:14px;"> _gxf_bootstrap_handler                  ; DATA XREF: _bootstrap_instructions+9C↑o</span></p><p><span style="font-family:Calibri;font-size:14px;">MRS             X0, #6, c15, c8, #3</span></p><p><span style="font-family:Calibri;font-size:14px;">TBNZ            W0, #0, loc_FFFFFFF009811660</span></p><p><span style="font-family:Calibri;font-size:14px;">ADRL            X0, _gxf_ppl_entry_handler ;</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #6, c15, c8, #1, X0</span></p><p><span style="font-family:Calibri;font-size:14px;">ADRL            X0, _GuardedExceptionVectorsBase</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #0, c12, c0, #0, X0</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">首先判断</span><span style="font-family:Calibri;">S3_6_C15_C8_3</span><span style="font-family:宋体;">寄存器的值是否为</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">，如果为</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">，就一直处于循环之中，可以推测出</span><span style="font-family:Calibri;">S3_6_C15_C8_3</span><span style="font-family:宋体;">寄存器作用是进入</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">的锁机制。然后将</span></span><span style="font-family:Calibri;font-size:14px;">_gxf_ppl_entry_handler</span><span style="font-family:宋体;font-size:14px;">函数重新存入了</span><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C8_1</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">寄存器，也就是说下次进入</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">时将会执行</span></span><span style="font-family:Calibri;font-size:14px;">_gxf_ppl_entry_handler</span><span style="font-family:宋体;font-size:14px;">函数。将</span><span style="font-family:Calibri;font-size:14px;">_GuardedExceptionVectorsBase</span><span style="font-family:宋体;font-size:14px;">地址写入</span><span style="font-family:Calibri;font-size:14px;">VBAR_EL1</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">寄存器，也就是说当</span><span style="font-family:Calibri;">cpu</span><span style="font-family:宋体;">在</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">时，</span></span><span style="font-family:Calibri;font-size:14px;">_GuardedExceptionVectorsBase</span><span style="font-family:宋体;font-size:14px;">函数负责其异常处理逻辑。</span></p><p><span style="font-family:Calibri;font-size:14px;">MRS             X1, #0, c0, c0, #5</span></p><p><span style="font-family:Calibri;font-size:14px;">UBFX            X2, X1, #8, #8</span></p><p><span style="font-family:Calibri;font-size:14px;">ADRL            X3, _cluster_offsets</span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X2, [X3,X2,LSL#3]</span></p><p><span style="font-family:Calibri;font-size:14px;">AND             X1, X1, #0xFF</span></p><p><span style="font-family:Calibri;font-size:14px;">ADD             X1, X1, X2</span></p><p><span style="font-family:Calibri;font-size:14px;">ADRL            X2, _pmap_cpu_data_array</span></p><p><span style="font-family:Calibri;font-size:14px;">CMP             X1, #6</span></p><p><span style="font-family:Calibri;font-size:14px;">B.CS            loc_FFFFFFF0098116A8</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X3, #0x180</span></p><p><span style="font-family:Calibri;font-size:14px;">MADD            X1, X1, X3, X2</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">首先从</span><span style="font-family:Calibri;">MPIDR_EL1</span><span style="font-family:宋体;">寄存器提取了</span><span style="font-family:Calibri;">cpu</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">cluster id</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">cpu id</span><span style="font-family:宋体;">，算出在</span></span><span style="font-family:Calibri;font-size:14px;">_pmap_cpu_data_array</span><span style="font-family:宋体;font-size:14px;">数组中的索引。</span><span style="font-family:Calibri;font-size:14px;">_pmap_cpu_data_array</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">是一个</span><span style="font-family:Calibri;">struct pmap_cpu_data</span><span style="font-family:宋体;">类型的数组。在</span><span style="font-family:Calibri;">XNU</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">source code</span><span style="font-family:宋体;">中有如下定义：</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">struct pmap_cpu_data {</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">#if XNU_MONITOR</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">void * ppl_kern_saved_sp;</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">void * ppl_stack;</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">arm_context_t * save_area;</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">unsigned int ppl_state;</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">#endif</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">}</span></span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X1, [X1,#0x10]</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             SP, X1</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">X1</span><span style="font-family:宋体;">保存的是当前</span><span style="font-family:Calibri;">cpu</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">struct pmap_cpu_data</span><span style="font-family:宋体;">结构体指针，</span><span style="font-family:Calibri;">0x10</span><span style="font-family:宋体;">偏移为</span><span style="font-family:Calibri;">save_area</span><span style="font-family:宋体;">，它指向了</span><span style="font-family:Calibri;">arm_context_t</span><span style="font-family:宋体;">类型的内存区域，将这个内存区域设置为</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">sp</span><span style="font-family:宋体;">地址。在从</span><span style="font-family:Calibri;">el1</span><span style="font-family:宋体;">进入</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">时，将全部的寄存器保存在这个区域。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">ADRP            X1, #_pmap_ppl_locked_down@PAGE</span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X2, [X1,#_pmap_ppl_locked_down@PAGEOFF]</span></p><p><span style="font-family:Calibri;font-size:14px;">CBZ             X2, loc_FFFFFFF0098116C0</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">接着判断</span><span style="font-family:Calibri;font-size:14px;">_pmap_ppl_locked_down</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">值是否为</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">，如果为</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">，则一直循环检查下去。在前面的</span><span style="font-family:Calibri;">machine_lockdown</span><span style="font-family:宋体;">函数中已经将</span></span><span style="font-family:Calibri;font-size:14px;">_pmap_ppl_locked_down</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">设置为了</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">，所以会继续运行下面的代码：</span></span></p><p><span style="font-family:Calibri;font-size:14px;">MOVK            X0, #0x2020,LSL#48</span></p><p><span style="font-family:Calibri;font-size:14px;">MOVK            X0, #0xA506,LSL#32</span></p><p><span style="font-family:Calibri;font-size:14px;">MOVK            X0, #0xF020,LSL#16</span></p><p><span style="font-family:Calibri;font-size:14px;">MOVK            X0, #0xF0E0</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #6, c15, c3, #0, X0</span></p><p><span style="font-family:Calibri;font-size:14px;">MOVK            X0, #0,LSL#48</span></p><p><span style="font-family:Calibri;font-size:14px;">MOVK            X0, #0,LSL#32</span></p><p><span style="font-family:Calibri;font-size:14px;">MOVK            X0, #0,LSL#16</span></p><p><span style="font-family:Calibri;font-size:14px;">MOVK            X0, #5</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #6, c15, c1, #2, X0</span></p><p><span style="font-family:Calibri;font-size:14px;">ADRL            X0, _invalid_ttep</span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X0, [X0]</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #0, c2, c0, #0, X0</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">将</span><span style="font-family:Calibri;">0x2020a506f020f0e0</span><span style="font-family:宋体;">赋值给了</span></span><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C3_0</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">寄存器，将</span><span style="font-family:Calibri;">0x5</span><span style="font-family:宋体;">赋值给了</span></span><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C1_2</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">寄存器，将</span><span style="font-family:Calibri;">_invalid_ttep</span><span style="font-family:宋体;">页表地址赋值给了</span></span><span style="font-family:Calibri;font-size:14px;">TTBR0_EL1</span><span style="font-family:宋体;font-size:14px;">。</span></p><p><span style="font-family:Calibri;font-size:14px;">SYS             #0, c8, c3, #0</span></p><p><span style="font-family:Calibri;font-size:14px;">DSB             ISH</span></p><p><span style="font-family:Calibri;font-size:14px;">ISB</span></p><p><span style="font-family:Calibri;font-size:14px;">DCD 0x201400</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">执行</span><span style="font-family:Calibri;font-size:14px;">0x201400</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">指令，退出</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">至此</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">全部初始化已经完成， </span><span style="font-family:Calibri;">el1</span><span style="font-family:宋体;">代码可以请求</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">的服务了。</span></span></p><p><span style="font-family:宋体;font-size:14px;"> </span></p><h1><span style="font-family:宋体;font-size:29px;">2. </span><strong><span style="font-family:宋体;font-size:29px;"><span style="font-family:Calibri;">Ppl</span><span style="font-family:宋体;">进入与退出</span></span></strong></h1><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">Ppl</span><span style="font-family:宋体;">给</span><span style="font-family:Calibri;">el1</span><span style="font-family:宋体;">代码提供了</span><span style="font-family:Calibri;">_gxf_ppl_enter</span><span style="font-family:宋体;">接口用于请求其服务。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">_arm_fast_fault_ppl:</span></p><p><span style="font-family:Calibri;font-size:14px;">mov     x15, #0x0</span></p><p><span style="font-family:Calibri;font-size:14px;">b       _gxf_ppl_enter</span></p><p><span style="font-family:Calibri;font-size:14px;">_arm_force_fast_fault_ppl:</span></p><p><span style="font-family:Calibri;font-size:14px;">mov     x15, #0x1</span></p><p><span style="font-family:Calibri;font-size:14px;">b       _gxf_ppl_enter</span></p><p><span style="font-family:Calibri;font-size:14px;">_mapping_free_prime_ppl:</span></p><p><span style="font-family:Calibri;font-size:14px;">mov     x15, #0x2</span></p><p><span style="font-family:Calibri;font-size:14px;">b       _gxf_ppl_enter</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">这里只罗列部分函数，</span><span style="font-family:Calibri;">x15</span><span style="font-family:宋体;">保存的是</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">服务表的索引。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">_gxf_ppl_enter:</span></p><p><span style="font-family:Calibri;font-size:14px;">fffffff008131c3c        pacibsp</span></p><p><span style="font-family:Calibri;font-size:14px;">fffffff008131c40        stp     x20, x21, [sp, #-0x20]! ; Latency: 6</span></p><p><span style="font-family:Calibri;font-size:14px;">fffffff008131c44        stp     x29, x30, [sp, #0x10]   ; Latency: 6</span></p><p><span style="font-family:Calibri;font-size:14px;">fffffff008131c48        add     x29, sp, #0x10</span></p><p><span style="font-family:Calibri;font-size:14px;">fffffff008131c4c        mrs     x9, TPIDR_EL1</span></p><p><span style="font-family:Calibri;font-size:14px;">fffffff008131c50        ldr     w10, [x9, #0x500]       ; Latency: 4</span></p><p><span style="font-family:Calibri;font-size:14px;">fffffff008131c54        add     w10, w10, #0x1</span></p><p><span style="font-family:Calibri;font-size:14px;">fffffff008131c58        str     w10, [x9, #0x500]       ; Latency: 4</span></p><p><span style="font-family:Calibri;font-size:14px;">fffffff008131c5c        adrp    x14, 5867 ; _pmap_ppl_locked_down</span></p><p><span style="font-family:Calibri;font-size:14px;">fffffff008131c60        add     x14, x14, #0x130</span></p><p><span style="font-family:Calibri;font-size:14px;">fffffff008131c64        ldr     x14, [x14]              ; Latency: 4</span></p><p><span style="font-family:Calibri;font-size:14px;">fffffff008131c68        cbz     x14, _ppl_bootstrap_dispatch</span></p><p><span style="font-family:Calibri;font-size:14px;">fffffff008131c6c        mrs     x14, S3_6_C15_C8_0</span></p><p><span style="font-family:Calibri;font-size:14px;">fffffff008131c70        cmp     x14, #0x0</span></p><p><span style="font-family:Calibri;font-size:14px;">fffffff008131c74        b.ne    0xfffffff008131c74</span></p><p><span style="font-family:Calibri;font-size:14px;">fffffff008131c78        mov     w10, #0x0</span></p><p><span style="font-family:Calibri;font-size:14px;">fffffff008131c7c        .long   0x00201420</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">首先检查</span><span style="font-family:Calibri;font-size:14px;"> _pmap_ppl_locked_down</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">是否为</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">，如果为</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">，说明</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">并没有初始化完成，直接跳转到</span></span><span style="font-family:Calibri;font-size:14px;">_ppl_bootstrap_dispatch</span><span style="font-family:宋体;font-size:14px;">函数：</span></p><p><span style="font-family:Calibri;font-size:14px;">CMP             X15, #0x47 ; &#39;G&#39;</span></p><p><span style="font-family:Calibri;font-size:14px;">B.CS            loc_FFFFFFF008131DD4</span></p><p><span style="font-family:Calibri;font-size:14px;">ADRL            X9, _ppl_handler_table</span></p><p><span style="font-family:Calibri;font-size:14px;">ADD             X9, X9, X15,LSL#3</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">X15</span><span style="font-family:宋体;">保存的是</span></span><span style="font-family:Calibri;font-size:14px;">_ppl_handler_table</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">的索引，如果大于</span><span style="font-family:Calibri;">0x47,</span><span style="font-family:宋体;">会触发</span><span style="font-family:Calibri;">panic</span><span style="font-family:宋体;">。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X10, [X9]</span></p><p><span style="font-family:Calibri;font-size:14px;">BLRAA           X10, X9</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">跳转到</span><span style="font-family:Calibri;font-size:14px;">_ppl_handler_table</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">[x15&lt;&lt;3]</span><span style="font-family:宋体;">去执行具体的服务函数。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X20, X0</span></p><p><span style="font-family:Calibri;font-size:14px;">BL              __enable_preemption</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X0, X20</span></p><p><span style="font-family:Calibri;font-size:14px;">LDP             X29, X30, [SP,#arg_10]</span></p><p><span style="font-family:Calibri;font-size:14px;">LDP             X20, X21, [SP+arg_0],#0x20</span></p><p><span style="font-family:Calibri;font-size:14px;">RETAB</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">在没有进入</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">情况下，直接通过</span><span style="font-family:Calibri;">ret</span><span style="font-family:宋体;">返回。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">如果</span><span style="font-family:Calibri;font-size:14px;">_pmap_ppl_locked_down</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">为</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">，则继续如下代码：</span></span></p><p><span style="font-family:Calibri;font-size:14px;">fffffff008131c78        mov     w10, #0x0</span></p><p><span style="font-family:Calibri;font-size:14px;">fffffff008131c7c        .long   0x00201420</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">将</span><span style="font-family:Calibri;">w10</span><span style="font-family:宋体;">设置为</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">， 这个很重要，后面会讲到。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">执行</span><span style="font-family:Calibri;font-size:14px;">0x00201420</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">进入</span><span style="font-family:Calibri;">EL1_Guard level, </span><span style="font-family:宋体;">前面在初始化时讲到</span><span style="font-family:Calibri;">cpu</span><span style="font-family:宋体;">进入</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">时，会执行</span></span><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C8_1</span><span style="font-family:宋体;font-size:14px;">寄存器指定的地址，也就是</span><span style="font-family:Calibri;font-size:14px;">_gxf_ppl_entry_handler</span><span style="font-family:宋体;font-size:14px;">。</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #5, #0</span></p><p><span style="font-family:Calibri;font-size:14px;">MRS             X9, #6, c15, c8, #3 ; S3_6_C15_C8_3</span></p><p><span style="font-family:Calibri;font-size:14px;">TBNZ            W9, #0, loc_FFFFFFF008131C88</span></p><p><span style="font-family:Calibri;font-size:14px;">MRS             X12, #6, c15, c9, #1 ; S3_6_C15_C9_1</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #0, c13, c0, #4, X12 ; TPIDR_EL1</span></p><p><span style="font-family:Calibri;font-size:14px;">MRS             X20, #0, c4, c0, #0 ; SPSR_EL1</span></p><p><span style="font-family:Calibri;font-size:14px;">AND             X20, X20, #0x3C0 ; mask FIQ; SET EL3t</span></p><p><span style="font-family:Calibri;font-size:14px;">B               _ppl_trampoline_start</span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">首先将</span><span style="font-family:Calibri;">SPSel</span><span style="font-family:宋体;">设置为</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">，然后判断</span></span><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C8_3</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">是否为</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">，否则一直循环等待，这再次证明</span></span><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C8_3</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">寄存器为进入</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">的锁机制。然后将</span><span style="font-family:Calibri;">S3_6_C15_C9_1</span><span style="font-family:宋体;">寄存器的值写入</span><span style="font-family:Calibri;">TPIDR_EL1</span><span style="font-family:宋体;">，说明它保存的是请求服务时的线程信息。将</span></span><span style="font-family:Calibri;font-size:14px;">SPSR_EL1</span><span style="font-family:宋体;font-size:14px;">设置为</span><span style="font-family:Calibri;font-size:14px;">mask FIQ; SET EL3t</span><span style="font-family:宋体;font-size:14px;">，为何是</span><span style="font-family:Calibri;font-size:14px;">EL3t</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">？</span> <span style="font-family:宋体;">接着跳入</span></span><span style="font-family:Calibri;font-size:14px;">_ppl_trampoline_start</span><span style="font-family:宋体;font-size:14px;">：</span></p><p><span style="font-family:Calibri;font-size:14px;">MOVK            X14, #0x2020,LSL#48</span></p><p><span style="font-family:Calibri;font-size:14px;">MOVK            X14, #0xA506,LSL#32</span></p><p><span style="font-family:Calibri;font-size:14px;">MOVK            X14, #0xF020,LSL#16</span></p><p><span style="font-family:Calibri;font-size:14px;">MOVK            X14, #0xF0E0 ; 0x2020a506f020f0e0</span></p><p><span style="font-family:Calibri;font-size:14px;">MRS             X21, #6, c15, c3, #0</span></p><p><span style="font-family:Calibri;font-size:14px;">CMP             X14, X21</span></p><p><span style="font-family:Calibri;font-size:14px;">B. </span><span style="font-family:Calibri;font-size:14px;">NE            loc_FFFFFFF00980D9AC</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">首先判断</span><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C3_0</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">寄存器的值是否为</span><span style="font-family:Calibri;">0x2020a506f020f0e0</span><span style="font-family:宋体;">，这个寄存器的作用笔者尚未搞清楚。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">CMP             X15, #0x47 ; &#39;G&#39;</span></p><p><span style="font-family:Calibri;font-size:14px;">B.CS            loc_FFFFFFF00980D9AC</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">再次判断</span><span style="font-family:Calibri;">x15</span><span style="font-family:宋体;">合法范围。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">MRS             X12, #0, c0, c0, #5 ; MPIDR_EL1</span></p><p><span style="font-family:Calibri;font-size:14px;">UBFX            X13, X12, #8, #8 ; get cluster id</span></p><p><span style="font-family:Calibri;font-size:14px;">ADRL            X14, _cluster_offsets</span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X13, [X14,X13,LSL#3] ; _cluster_offsets[index&lt;&lt;3]</span></p><p><span style="font-family:Calibri;font-size:14px;">AND             X12, X12, #0xFF</span></p><p><span style="font-family:Calibri;font-size:14px;">ADD             X12, X12, X13</span></p><p><span style="font-family:Calibri;font-size:14px;">ADRL            X13, _pmap_cpu_data_array</span></p><p><span style="font-family:Calibri;font-size:14px;">CMP             X12, #6</span></p><p style="margin-left:0;text-indent:0;"><span style="font-family:Calibri;font-size:14px;">C. </span><span style="font-family:Calibri;font-size:14px;">CS            loc_FFFFFFF00980D92C</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X14, #0x180</span></p><p><span style="font-family:Calibri;font-size:14px;">MADD            X12, X12, X14, X13</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">得到当前</span><span style="font-family:Calibri;">cpu</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">struct pmap_cpu_data</span><span style="font-family:宋体;">结构体指针。</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">L</span></span><span style="font-family:Calibri;font-size:14px;">DR             W9, [X12,#0x18] ; _pmap_cpu_data-&gt;ppl_state</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">W9</span><span style="font-family:宋体;">保存的是</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">的当前状态</span></span><span style="font-family:Calibri;font-size:14px;">ppl_state</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">，</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">的状态有</span><span style="font-family:Calibri;">3</span><span style="font-family:宋体;">个定义：</span></span></p><p><span style="font-family:Calibri;font-size:14px;">PPL_STATE_KERNEL</span></p><p><span style="font-family:Calibri;font-size:14px;">PPL_STATE_DISPATCH</span></p><p><span style="font-family:Calibri;font-size:14px;">PPL_STATE_EXCEPTION</span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;">_ppl_trampoline_start</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">这个函数可以由</span><span style="font-family:Calibri;">ppl_enter</span><span style="font-family:宋体;">由</span><span style="font-family:Calibri;">el1</span><span style="font-family:宋体;">代码主动调用，也可以由</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">的异常处理调用，在后面会分析到。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">CMP             W9, #0  ; PPL_STATE_KERNEL</span></p><p><span style="font-family:Calibri;font-size:14px;">B. </span><span style="font-family:Calibri;font-size:14px;">EQ            loc_FFFFFFF00980D970</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">W9</span><span style="font-family:宋体;">为</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">，即</span></span><span style="font-family:Calibri;font-size:14px;">PPL_STATE_KERNEL</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">，表示可以请求</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">服务。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">loc_FFFFFFF00980D970                    ; CODE XREF: _ppl_trampoline_start+60↑j</span></p><p><span style="font-family:Calibri;font-size:14px;">CMP             W10, #0</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">判断</span><span style="font-family:Calibri;">w10</span><span style="font-family:宋体;">是否为</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">，注意在前面的</span><span style="font-family:Calibri;">ppl_enter</span><span style="font-family:宋体;">路径中，已经将</span><span style="font-family:Calibri;">w10</span><span style="font-family:宋体;">设置为了</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">，所以代码可以进行前进。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">B.NE            loc_FFFFFFF00980D9AC</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W13, #1</span></p><p><span style="font-family:Calibri;font-size:14px;">STR             W13, [X12,#0x18] ; enter PPL_STATE_DISPATCH mode</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">更改</span><span style="font-family:Calibri;">ppl_state</span><span style="font-family:宋体;">状态为</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">，即</span></span><span style="font-family:Calibri;font-size:14px;"> PPL_STATE_DISPATCH</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">，表示</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">正处在服务派发状态中。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X9, [X12,#8] ; _pmap_cpu_data-&gt;ppl_stack</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X21, SP</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             SP, X9</span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;">_pmap_cpu_data-&gt;ppl_stack</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">保存的是</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">服务要使用的</span><span style="font-family:Calibri;">stack</span><span style="font-family:宋体;">区域。注意</span></span><span style="font-family:Calibri;font-size:14px;">_pmap_cpu_data-&gt;</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">save_area</span><span style="font-family:宋体;">保存的是进入</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">异常处理时保存全部寄存器用的栈区域。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">STR             X21, [X12] ; save old el1 sp</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">保存</span><span style="font-family:Calibri;">el1</span><span style="font-family:宋体;">原来的</span><span style="font-family:Calibri;">sp</span><span style="font-family:宋体;">到</span></span><span style="font-family:Calibri;font-size:14px;">_pmap_cpu_data-&gt;</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">ppl_kern_saved_sp</span><span style="font-family:宋体;">，以后退出</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">服务时还要恢复原来的</span><span style="font-family:Calibri;">stack</span><span style="font-family:宋体;">指针。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">ADRL            X9, _ppl_handler_table</span></p><p><span style="font-family:Calibri;font-size:14px;">ADD             X9, X9, X15,LSL#3 ; _ppl_handler_table[index&lt;&lt;3]</span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X10, [X9]</span></p><p><span style="font-family:Calibri;font-size:14px;">B               _ppl_dispatch</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">X10</span><span style="font-family:宋体;">保存了具体的服务函数地址</span></span><span style="font-family:Calibri;font-size:14px;">_ppl_handler_table</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">[x15&lt;&lt;3]</span><span style="font-family:宋体;">，然后跳转到</span></span><span style="font-family:Calibri;font-size:14px;">_ppl_dispatch</span><span style="font-family:宋体;font-size:14px;">执行，在屏蔽了一些列中断后，进行执行：</span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">BLRAA           X10, X9</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">调用具体的</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">服务函数。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">__PPLTEXT:__text:FFFFFFF00980D9B8</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X15, #0</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             SP, X21</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X10, X20</span></p><p><span style="font-family:Calibri;font-size:14px;">STR             XZR, [X12]</span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             W9, [X12,#0x18] ; _pmap_cpu_data-&gt;ppl_state</span></p><p><span style="font-family:Calibri;font-size:14px;">CMP             W9, #1  ; PPL_STATE_DISPATCH</span></p><p><span style="font-family:Calibri;font-size:14px;">B.NE            loc_FFFFFFF00980D9D0</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W9, #0</span></p><p><span style="font-family:Calibri;font-size:14px;">STR             W9, [X12,#0x18] ; PPL_STATE_KERNEL</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">服务执行完之后，要把</span><span style="font-family:Calibri;">ppl_state</span><span style="font-family:宋体;">再次设置</span></span><span style="font-family:Calibri;font-size:14px;"> PPL_STATE_KERNEL</span><span style="font-family:宋体;font-size:14px;">。</span></p><p><span style="font-family:Calibri;font-size:14px;">B               ppl_return_to_kernel_mode</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">最后调用</span><span style="font-family:Calibri;font-size:14px;">ppl_return_to_kernel_mode</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">退出</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">，返回</span><span style="font-family:Calibri;">el1</span><span style="font-family:宋体;">代码。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">ADRL            X14, ppl_exit</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #0, c4, c0, #1, X14 ; ELR_EL1</span></p><p><span style="font-family:Calibri;font-size:14px;">MRS             X14, #6, c15, c8, #3</span></p><p><span style="font-family:Calibri;font-size:14px;">AND             X14, X14, #0xFFFFFFFFFFFFFFFE</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #6, c15, c8, #3, X14 ; S3_6_C15_C8_3</span></p><p><span style="font-family:Calibri;font-size:14px;">MRS             X14, #0, c4, c0, #0 ; SPSR_EL1</span></p><p><span style="font-family:Calibri;font-size:14px;">AND             X14, X14, #0xFFFFFFFFFFFFFC3F</span></p><p><span style="font-family:Calibri;font-size:14px;">ORR             X14, X14, X10</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #0, c4, c0, #0, X14 ; SPSR_EL1 -&gt; EL3h</span></p><p><span style="font-family:Calibri;font-size:14px;">MRS             X14, #0, c13, c0, #4 ; TPIDR_EL1</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #6, c15, c9, #1, X14 ; S3_6_C15_C9_1</span></p><p><span style="font-family:Calibri;font-size:14px;">DCQ 0x201400</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">首先将</span><span style="font-family:Calibri;font-size:14px;">ELR_EL1</span><span style="font-family:宋体;font-size:14px;">设置为</span><span style="font-family:Calibri;font-size:14px;">ppl_exit</span><span style="font-family:宋体;font-size:14px;">，然后将</span><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C8_3</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">的最低位清</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">，然后将</span></span><span style="font-family:Calibri;font-size:14px;">SPSR_EL1</span><span style="font-family:宋体;font-size:14px;">设置为</span><span style="font-family:Calibri;font-size:14px;"> EL3h</span><span style="font-family:宋体;font-size:14px;">，注意</span><span style="font-family:Calibri;font-size:14px;">SPSR_EL</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">的第</span><span style="font-family:Calibri;">2</span><span style="font-family:宋体;">个</span><span style="font-family:Calibri;">bit</span><span style="font-family:宋体;">设置为了</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">，在</span><span style="font-family:Calibri;">arm</span><span style="font-family:宋体;">手册里这个</span><span style="font-family:Calibri;">bit</span><span style="font-family:宋体;">是保留的，说明苹果处理器使用了这个</span><span style="font-family:Calibri;">bit</span><span style="font-family:宋体;">代表</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">的执行状态，但是很奇怪为啥都设置为</span></span><span style="font-family:Calibri;font-size:14px;">EL3h</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">,</span><span style="font-family:宋体;">而不是</span></span><span style="font-family:Calibri;font-size:14px;">EL</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">1</span></span><span style="font-family:Calibri;font-size:14px;">h</span><span style="font-family:宋体;font-size:14px;">？随后将</span><span style="font-family:Calibri;font-size:14px;">TPIDR_EL1</span><span style="font-family:宋体;font-size:14px;">值保存在了</span><span style="font-family:Calibri;font-size:14px;">S3_6_C15_C9_1</span><span style="font-family:宋体;font-size:14px;">寄存器。</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">最后执行</span><span style="font-family:Calibri;font-size:14px;">0x201400</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">退出</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">，由于</span></span><span style="font-family:Calibri;font-size:14px;">ELR_EL1</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">寄存器保存的是</span><span style="font-family:Calibri;">ppl_exit</span><span style="font-family:宋体;">，</span><span style="font-family:Calibri;">cpu</span><span style="font-family:宋体;">跳转到</span><span style="font-family:Calibri;">ppl_exit</span><span style="font-family:宋体;">继续执行</span><span style="font-family:Calibri;">, ppl_exit</span><span style="font-family:宋体;">恢复之前屏蔽的中断，然后使用</span><span style="font-family:Calibri;">ret</span><span style="font-family:宋体;">指令返回。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">上面分析的是一个正常通过</span><span style="font-family:Calibri;">ppl_enter</span><span style="font-family:宋体;">请求</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">服务的路径。下面继续返回</span></span><span style="font-family:Calibri;font-size:14px;">_ppl_trampoline_start</span><span style="font-family:宋体;font-size:14px;">代码。</span></p><p><span style="font-family:Calibri;font-size:14px;">CMP             W9, #1  ; PPL_STATE_DISPATCH</span></p><p style="margin-left:0;text-indent:0;"><span style="font-family:Calibri;font-size:14px;">C. </span><span style="font-family:Calibri;font-size:14px;">EQ            loc_FFFFFFF00980D9A4 ; _pmap_cpu_data_array-&gt;ppl_kern_saved_sp</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">如果当前</span><span style="font-family:Calibri;">ppl_state</span><span style="font-family:宋体;">状态为</span></span><span style="font-family:Calibri;font-size:14px;">PPL_STATE_DISPATCH</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">，表示有其他</span><span style="font-family:Calibri;">cpu</span><span style="font-family:宋体;">正在请求</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">服务，因此恢复之前通过</span></span><span style="font-family:Calibri;font-size:14px;">_pmap_cpu_data_array-&gt;ppl_kern_saved_s</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">p</span><span style="font-family:宋体;">保存的栈，然后退出</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">，前面的路径已经分析过了。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">CMP             W9, #3  ; PPL_STATE_EXCEPTION</span></p><p><span style="font-family:Calibri;font-size:14px;">B. </span><span style="font-family:Calibri;font-size:14px;">NE            loc_FFFFFFF00980D9AC</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">如果</span><span style="font-family:Calibri;">ppl_state</span><span style="font-family:宋体;">也不是</span></span><span style="font-family:Calibri;font-size:14px;">PPL_STATE_EXCEPTION</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">，则直接退出</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">CMP             W10, #3 ; PPL_STATE_EXCEPTION</span></p><p style="margin-left:0;text-indent:0;"><span style="font-family:Calibri;font-size:14px;">C. </span><span style="font-family:Calibri;font-size:14px;">NE            loc_FFFFFFF00980D9AC</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W9, #1</span></p><p><span style="font-family:Calibri;font-size:14px;">STR             W9, [X12,#0x18] ; PPL_STATE_DISPATCH</span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X0, [X12,#0x10] ; _pmap_cpu_data_array-&gt;save_area</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             SP, X0</span></p><p><span style="font-family:Calibri;font-size:14px;">B               _return_to_ppl</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">将</span><span style="font-family:Calibri;">sp</span><span style="font-family:宋体;">设置为</span></span><span style="font-family:Calibri;font-size:14px;">_pmap_cpu_data_array-&gt;save_area</span><span style="font-family:宋体;font-size:14px;">，</span><span style="font-family:Calibri;font-size:14px;">_return_to_ppl</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">要使用这个栈恢复之前进入</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">异常处理时保存的全部寄存器值，恢复</span><span style="font-family:Calibri;">cpsr,  ELR_EL1</span><span style="font-family:宋体;">设置原来的调用地址，恢复</span><span style="font-family:Calibri;">bp,sp</span><span style="font-family:宋体;">，通过</span><span style="font-family:Calibri;">eret</span><span style="font-family:宋体;">返回原来的</span><span style="font-family:Calibri;">el1</span><span style="font-family:宋体;">路径中。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">为啥要判断</span><span style="font-family:Calibri;">w10</span><span style="font-family:宋体;">的值是否为</span><span style="font-family:Calibri;">3</span><span style="font-family:宋体;">？这个路径表示的是</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">异常处理路径中要请求</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">服务。</span></span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;">_GuardedExceptionVectorsBase</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">是</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">异常处理地址，我们看到它只对</span><span style="font-family:Calibri;">0x000</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">offset</span><span style="font-family:宋体;">使用了有效函数，表明它只处理来自同层</span><span style="font-family:Calibri;">current level</span><span style="font-family:宋体;">的异常处理，再次证明</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">也是在</span><span style="font-family:Calibri;">EL1 level</span><span style="font-family:宋体;">上。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">__PPLTEXT:__text:FFFFFFF0098114B0 gtr_sync</span><span style="font-family:宋体;font-size:14px;">：</span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             X26, #1</span></span></p><p><span style="font-family:Calibri;font-size:14px;">ADRL            X1, _fleh_synchronous ; ESR_EL1</span></p><p><span style="font-family:Calibri;font-size:14px;">MSR             #0, c4, c0, #1, X1 ; ELR_EL1</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">可以看到</span><span style="font-family:Calibri;">gtr_sync</span><span style="font-family:宋体;">把</span></span><span style="font-family:Calibri;font-size:14px;">_fleh_synchronous</span><span style="font-family:宋体;font-size:14px;">赋值给了</span><span style="font-family:Calibri;font-size:14px;">ELR_EL1</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">，</span> <span style="font-family:Calibri;">x26</span><span style="font-family:宋体;">设置为</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">很关键，这是一个标识，后面会讲到。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X0, SP</span></p><p><span style="font-family:Calibri;font-size:14px;">DCD 0x201400</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">随后</span><span style="font-family:Calibri;">gtr_sync</span><span style="font-family:宋体;">使用</span></span><span style="font-family:Calibri;font-size:14px;">0x201400</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">指令退出了</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">，转而执行</span><span style="font-family:Calibri;">el1 </span></span><span style="font-family:Calibri;font-size:14px;">_fleh_synchronous</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">函数，这是</span><span style="font-family:Calibri;">el1</span><span style="font-family:宋体;">内核异常处理的主要函数，这说明</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">的主要处理逻辑会使用</span><span style="font-family:Calibri;">el1</span><span style="font-family:宋体;">内核代码，这也就解释了</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">为什么能保护内核态和用户态的数据。以前我们在使用</span><span style="font-family:Calibri;">el2</span><span style="font-family:宋体;">做保护时，只能保护</span><span style="font-family:Calibri;">el1</span><span style="font-family:宋体;">的数据，因为</span><span style="font-family:Calibri;">el1</span><span style="font-family:宋体;">的使用的代码和数据都已经是映射好的，而</span><span style="font-family:Calibri;">el0</span><span style="font-family:宋体;">层用户的代码和数据会涉及到很多缺页异常处理的逻辑，比如页表不存在，或者页表被交换到磁盘上，这会使</span><span style="font-family:Calibri;">el2</span><span style="font-family:宋体;">的异常处理逻辑非常复杂。</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">使用</span><span style="font-family:Calibri;">el1</span><span style="font-family:宋体;">内核代码的处理逻辑就简化了自身的代码逻辑，性能也会提升不少。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">__TEXT_EXEC:__text:FFFFFFF0081315CC _fleh_synchronous</span></p><p><span style="font-family:Calibri;font-size:14px;">BL              _sleh_synchronous</span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;">_fleh_synchronous</span><span style="font-family:宋体;font-size:14px;">又调用了</span><span style="font-family:Calibri;font-size:14px;">_sleh_synchronous</span><span style="font-family:宋体;font-size:14px;">，这个函数是异常处理逻辑的主要处理函数。</span></p><p><span style="font-family:Calibri;font-size:14px;">CMP             X26, XZR</span></p><p><span style="font-family:Calibri;font-size:14px;">B. </span><span style="font-family:Calibri;font-size:14px;">EQ            loc_FFFFFFF00813161C</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">注意</span><span style="font-family:Calibri;font-size:14px;">_fleh_synchronous</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">是</span><span style="font-family:Calibri;">el1</span><span style="font-family:宋体;">内核代码的处理逻辑，</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">是借用了它的代码，在前面看到</span><span style="font-family:Calibri;">gtr_sync</span><span style="font-family:宋体;">把</span><span style="font-family:Calibri;">x26</span><span style="font-family:宋体;">设置为了</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">，在</span></span><span style="font-family:Calibri;font-size:14px;">_fleh_synchronous</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">函数里表示此次请求来自</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X15, #0</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W10, #3</span></p><p><span style="font-family:Calibri;font-size:14px;">DCB 0x20, 0x14, 0x20, 0</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">然后将</span><span style="font-family:Calibri;">x15</span><span style="font-family:宋体;">设置为</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">，</span><span style="font-family:Calibri;">w10</span><span style="font-family:宋体;">设置为</span><span style="font-family:Calibri;">3</span><span style="font-family:宋体;">，最后调用</span></span><span style="font-family:Calibri;font-size:14px;">0x2014</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">2</span></span><span style="font-family:Calibri;font-size:14px;">0</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">再次进入</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">，此时就会跳转到</span></span><span style="font-family:Calibri;font-size:14px;">_ppl_trampoline_start</span><span style="font-family:宋体;font-size:14px;">的异常处理请求路径里：</span></p><p><span style="font-family:Calibri;font-size:14px;">CMP             W9, #3  ; PPL_STATE_EXCEPTION</span></p><p><span style="font-family:Calibri;font-size:14px;">B.NE            loc_FFFFFFF00980D9AC</span></p><p><span style="font-family:Calibri;font-size:14px;">CMP             W10, #3 ; PPL_STATE_EXCEPTION</span></p><p><span style="font-family:Calibri;font-size:14px;">B.NE            loc_FFFFFFF00980D9AC</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W9, #1</span></p><p><span style="font-family:Calibri;font-size:14px;">STR             W9, [X12,#0x18] ; PPL_STATE_DISPATCH</span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X0, [X12,#0x10] ; _pmap_cpu_data_array-&gt;save_area</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             SP, X0</span></p><p><span style="font-family:Calibri;font-size:14px;">B               _return_to_ppl</span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;">_return_to_ppl</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">恢复</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">异常处理时保存的全部寄存器值，恢复</span><span style="font-family:Calibri;">cpsr,  ELR_EL1</span><span style="font-family:宋体;">设置原来的调用地址，恢复</span><span style="font-family:Calibri;">bp,sp</span><span style="font-family:宋体;">，通过</span><span style="font-family:Calibri;">eret</span><span style="font-family:宋体;">返回原来的</span><span style="font-family:Calibri;">el1</span><span style="font-family:宋体;">路径中。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h1><span style="font-family:宋体;font-size:29px;">3. </span><strong><span style="font-family:宋体;font-size:29px;"><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">服务</span></span></strong></h1><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;">_ppl_handler_table</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">数组保存的是</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">服务函数地址。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">_ppl_handler_table</span><span style="font-family:宋体;font-size:14px;">：</span></p><p><span style="font-family:Calibri;font-size:14px;">_arm_force_fast_fault_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_mapping_free_prime_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_phys_attribute_clear_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_phys_attribute_set_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_batch_set_cache_attributes_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_change_wiring_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_create_options_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_destroy_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_enter_options_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_find_pa_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_insert_sharedpage_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_is_empty_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_map_cpu_windows_copy_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_mark_page_as_ppl_page_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_nest_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_page_protect_options_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_protect_options_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_query_page_info_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_query_resident_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_reference_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_remove_options_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_return_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_set_cache_attributes_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_set_nested_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_set_process_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_switch_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_switch_user_ttb_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_clear_user_ttb_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_unmap_cpu_windows_copy_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_unnest_options_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_footprint_suspend_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_cpu_data_init_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_release_ppl_pages_to_kernel_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_set_jit_entitled_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_load_legacy_trust_cache_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_load_image4_trust_cache_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_is_trust_cache_loaded_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_lookup_in_static_trust_cache_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_lookup_in_loaded_trust_caches_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_cs_cd_register_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_cs_cd_unregister_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_cs_associate_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_cs_lookup_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_cs_check_overlap_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_iommu_init_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_iommu_iovmalloc_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_iommu_map_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_iommu_unmap_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_iommu_iovmfree_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_iommu_ioctl_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_iommu_grant_page_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_update_compressor_page_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_trim_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_ledger_alloc_init_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_ledger_alloc_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_ledger_free_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_sign_user_ptr_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_pmap_auth_user_ptr_internal</span></p><p><span style="font-family:Calibri;font-size:14px;">_phys_attribute_clear_range_internal</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">可以看到</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">服务代码是非常复杂的，覆盖了物理内存和虚拟内存管理的方方面面。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h2 style="margin-left:0;text-indent:0;"><span style="font-family:Arial;font-size:21px;">3.1 </span><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">_pmap_mark_page_as_ppl_page_internal</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">我们先看下如何将一个物理页标记为</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">使用的物理页。</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">_pmap_mark_page_as_ppl_page_internal</span><span style="font-family:宋体;">：</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             X19, X0</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">ADRP            X23, #_vm_first_phys@PAGE ; x0(pa) &gt; vm_first_phys &amp;&amp; x0 &lt; vm_last_phys</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">LDR             X8, [X23,#_vm_first_phys@PAGEOFF]</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">ADRP            X24, #_vm_last_phys@PAGE</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">LDR             X9, [X24,#_vm_last_phys@PAGEOFF]</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">CMP             X8, X0</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">CCMP            X9, X0, #0, LS</span></span></p><p style="margin-left:0;text-indent:0;"><span style="font-family:宋体;font-size:14px;">C. </span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">LS            loc_FFFFFFF0097FB5B0</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">X0</span><span style="font-family:宋体;">保存的是要标记的物理地址</span><span style="font-family:Calibri;">pa</span><span style="font-family:宋体;">，然后检查它是否在</span><span style="font-family:Calibri;">_vm_first_phys</span><span style="font-family:宋体;">与</span><span style="font-family:Calibri;">_vm_last_phys</span><span style="font-family:宋体;">之间，这是</span><span style="font-family:Calibri;">XNU</span><span style="font-family:宋体;">管理的有效物理内存区间。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X11, [X9,#_pp_attr_table@PAGEOFF]</span></p><p><span style="font-family:Calibri;font-size:14px;">LDRSH           W10, [X11,X8,LSL#1]</span></p><p><span style="font-family:Calibri;font-size:14px;">TBNZ            W10, #0x1F, loc_FFFFFFF0097FB580 ;</span></p><p><span style="font-family:Calibri;font-size:14px;">ORR             W12, W10, #0x4000 ; pp_attr_table[pai] &amp; 0x4000</span></p><p><span style="font-family:Calibri;font-size:14px;">ADD             X11, X11, X8,LSL#1</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             X13, X10</span></p><p><span style="font-family:Calibri;font-size:14px;">CASALH          W13, W12, [X11]</span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;">pp_attr_table[pai] &amp;</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">=</span></span><span style="font-family:Calibri;font-size:14px;"> 0x4000</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">，将</span><span style="font-family:Calibri;">pa</span><span style="font-family:宋体;">对应的</span><span style="font-family:Calibri;">pp_attr_table</span><span style="font-family:宋体;">进行标记。</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">LDR             X9, [X21,#_pv_head_table@PAGEOFF]</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">ADD             X8, X9, X8,LSL#3</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">ADD             X8, X8, #4</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             W9, #0x20000000</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">LDCLRL          W9, W8, [X8] ;</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">_pv_head_table[index] &amp;= 0x20000000</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             X0, X19</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">BL              _phystokv</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">ADD             X1, X0, #4,LSL#12</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             W2, #3</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">MOV             W3, #1</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">BL              _pmap_set_range_xprr_perm</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">在对</span><span style="font-family:Calibri;font-size:14px;">pp_attr_table</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">_pv_head_table</span><span style="font-family:宋体;">进行标记后，调用</span><span style="font-family:Calibri;">_pmap_set_range_xprr_perm</span><span style="font-family:宋体;">函数，这个函数作用是将虚拟地址</span><span style="font-family:Calibri;">va</span><span style="font-family:宋体;">，到</span><span style="font-family:Calibri;">va + size</span><span style="font-family:宋体;">之间的所有虚拟地址对应的页表属性进行转换，第三个参数代表的是原来页表的权限属性，第四个参数代表的是新的页表属性，这个函数用来在内核页表和</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">页表之间进行权限转换。</span></span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.9087018544935807" data-s="300,640" style="" data-type="png" data-w="701" src="https://wechat2rss.xlab.app/img-proxy/?k=3b2f20cf&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F4iaJia7Cvd3PCUNWThdNcFzsbyAuM3eyKVMAvLibB0QlNnSmOapLPmS8x6GBKica7UPgSfBVLbNMZeFdqeTQzarWicw%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="1.0271041369472182" data-s="300,640" style="" data-type="png" data-w="701" src="https://wechat2rss.xlab.app/img-proxy/?k=f8610c4a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F4iaJia7Cvd3PCUNWThdNcFzsbyAuM3eyKVRS0v2y6hhhFABVKAOro8IpnhAyUyfxmLyViaQNgicib0iawbHF8icVUrxTw%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="1.1188589540412044" data-s="300,640" style="" data-type="png" data-w="631" src="https://wechat2rss.xlab.app/img-proxy/?k=0fed8f80&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F4iaJia7Cvd3PCUNWThdNcFzsbyAuM3eyKVTIu4WrB82srtL0uLmPe4YiaRHd7R1Xzty3EFgShRHTbndQLRtiaIBELg%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.3200663349917081" data-s="300,640" style="" data-type="png" data-w="603" src="https://wechat2rss.xlab.app/img-proxy/?k=1268e368&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F4iaJia7Cvd3PCUNWThdNcFzsbyAuM3eyKVib5I3d31nRLsCps56rlqgc9SYFWOhNW3rW4y2NS0wWA4GsWkvW8zeYA%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:Calibri;font-size:14px;"></span><br/></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">首先检查要进行转换的虚拟地址合法范围，只能在</span><span style="font-family:Calibri;">physmap_base</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">physmap_end</span><span style="font-family:宋体;">或者</span><span style="font-family:Calibri;">gVirtBase</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">static_memory_end</span><span style="font-family:宋体;">之间。接下来就是要循环遍历</span><span style="font-family:Calibri;">l3</span><span style="font-family:宋体;">页表，</span><span style="font-family:Calibri;">l0</span><span style="font-family:宋体;">页表基地址保存在</span><span style="font-family:Calibri;">kernel_pmap-&gt;tte</span><span style="font-family:宋体;">，这个页表保存的是内核使用的页表地址，在内核启动时进行初始化。然后找到虚拟地址对应的</span><span style="font-family:Calibri;">l3 table</span><span style="font-family:宋体;">地址， 循环遍历它的每个页表项，在这之前还需要将虚拟地址转换为物理地址，然后找到物理地址对应的</span><span style="font-family:Calibri;">pv_head_table</span><span style="font-family:宋体;">表项，将其上锁。然后开始提取</span><span style="font-family:Calibri;">l3</span><span style="font-family:宋体;">页表项的原始权限，请看如下代码逻辑：</span></span></p><p><span style="font-family:Calibri;font-size:14px;">LDR             X8, [X20] ; </span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">获得</span><span style="font-family:Calibri;">pte</span><span style="font-family:宋体;">的内容</span></span></p><p><span style="font-family:Calibri;font-size:14px;">TBZ             W8, #1, loc_FFFFFFF007B598C4 ;</span><span style="font-family:宋体;font-size:14px;">判断页表有效位</span></p><p><span style="font-family:Calibri;font-size:14px;">TBNZ            X8, #0x34, loc_FFFFFFF007B598FC ; &#39;4&#39; ; ARM_PTE_HINT_MASK</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">LSR             X9, X8, #4</span><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"> </span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">AND             X9, X9, #0xC ; (*pte &gt;&gt; 4) &amp; 0xc; </span><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:宋体;">提取</span><span style="font-family:Calibri;">ap</span><span style="font-family:宋体;">权限</span></span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">LSR             X10, X8, #0x35 ; &#39;5&#39; ; *pte &gt;&gt; 53</span><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:宋体;">，提取</span><span style="font-family:Calibri;">xn</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">pxn</span><span style="font-family:宋体;">权限</span></span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">BFXIL           X9, X8, #0x35, #1 ; &#39;5&#39;</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">AND             X10, X10, #2 ; (*pte &gt;&gt; 53) &amp; 2</span></p><p><span style="font-family:Calibri;font-size:14px;">ORR             X9, X9, X10</span></p><p><span style="font-family:Calibri;font-size:14px;">CMP             X9, X26 ; </span><span style="font-family:宋体;font-size:14px;">与函数的第三个参数</span><span style="font-family:Calibri;font-size:14px;">expected_perm</span><span style="font-family:宋体;font-size:14px;">比较</span></p><p><span style="font-family:Calibri;font-size:14px;">B. </span><span style="font-family:Calibri;font-size:14px;">NE            loc_FFFFFFF007B59938</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">通过上面的提取后获得一个</span><span style="font-family:Calibri;">4bit</span><span style="font-family:宋体;">的权限值，高</span><span style="font-family:Calibri;">2</span><span style="font-family:宋体;">位代表</span><span style="font-family:Calibri;">ap</span><span style="font-family:宋体;">权限，最低位代表</span><span style="font-family:Calibri;">pxn</span><span style="font-family:宋体;">权限，第</span><span style="font-family:Calibri;">2bit</span><span style="font-family:宋体;">代表</span><span style="font-family:Calibri;">xn</span><span style="font-family:宋体;">权限。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">所以可以推断出</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">新的权限模型为</span><span style="font-family:Calibri;">4</span><span style="font-family:宋体;">个</span><span style="font-family:Calibri;">bit</span><span style="font-family:宋体;">：</span></span></p><p style="text-indent:98px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">new_perm</span></span></p><p style="text-indent:98px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">X XXX</span></span></p><p><span style="font-family:宋体;font-size:14px;">            <span style="font-family:Calibri;">/  /  \ \</span></span></p><p style="text-indent:70px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">/  /     \ \</span></span></p><p><span style="font-family:宋体;font-size:14px;">       <span style="font-family:Calibri;">54  53      7  6</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">+-------------------------------------------------------</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">|      |xn|pxn| ...  |ap| |          |</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">--------------------------------------------------------</span></span></p><p><span style="font-family:宋体;font-size:14px;"> </span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">El1</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">EL1_Guard level</span><span style="font-family:宋体;">对应的权限关系可以参考</span><span style="font-family:Calibri;">m1n1</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">dock</span><span style="font-family:宋体;">：</span></span></p><p style="text-indent:28px;"><span style="text-decoration:underline;"><span style="font-family: 宋体;color: rgb(0, 0, 255);font-size: 16px;">HW: SPRR and GXF · AsahiLinux/docs Wiki · GitHub</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:16px;"> </span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="1.25879917184265" data-s="300,640" style="" data-type="png" data-w="483" src="https://wechat2rss.xlab.app/img-proxy/?k=c701ab0f&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F4iaJia7Cvd3PCUNWThdNcFzsbyAuM3eyKV6fsB15YIFQqFncFicB7rnBUibBB97QB77bJ00rqlS5qwgdmwTPJehSqg%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:宋体;font-size:16px;"> </span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">通过搜索代码，发现有以下几个函数调用了</span><span style="font-family:Calibri;font-size:14px;">_pmap_set_range_xprr_perm</span><span style="font-family:宋体;font-size:14px;">：</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,0,0);background:rgb(255,0,0);">_pmap_mark_page_as_kernel_page</span><span style="font-family:宋体;font-size:14px;background:rgb(255,0,0);background:rgb(255,0,0);"><span style="font-family:Calibri;">:</span></span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W2, </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">#1</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W3, </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">#3</span></p><p><span style="font-family:Calibri;font-size:14px;">B               _pmap_set_range_xprr_perm</span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,0,0);background:rgb(255,0,0);">_pmap_mark_page_as_ppl_page_internal</span><span style="font-family:宋体;font-size:14px;background:rgb(255,0,0);background:rgb(255,0,0);"><span style="font-family:Calibri;">:</span></span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W2, </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">#3</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W3, </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">#1</span></p><p><span style="font-family:Calibri;font-size:14px;">BL              _pmap_set_range_xprr_perm</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">可以看到将普通的内核权限转化为</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">权限，是将</span><span style="font-family:Calibri;">3</span><span style="font-family:宋体;">替换为</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">。反过来则是</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">替换为</span><span style="font-family:Calibri;">3</span><span style="font-family:宋体;">。我们可以推测</span><span style="font-family:Calibri;">3</span><span style="font-family:宋体;">为</span><span style="font-family:Calibri;">RW</span><span style="font-family:宋体;">读写权限，</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">则为</span><span style="font-family:Calibri;">R</span><span style="font-family:宋体;">只读权限。</span></span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,0,0);background:rgb(255,0,0);">_pmap_static_allocations_done</span><span style="font-family:宋体;font-size:14px;background:rgb(255,0,0);background:rgb(255,0,0);"><span style="font-family:Calibri;">:</span></span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W2, </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">#3</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W3, </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">#0xB</span></p><p><span style="font-family:Calibri;font-size:14px;">BL              _pmap_set_range_xprr_perm</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">将</span><span style="font-family:Calibri;">_bootstrap_pagetables</span><span style="font-family:宋体;">从</span><span style="font-family:Calibri;">0x3</span><span style="font-family:宋体;">设置为</span><span style="font-family:Calibri;">0xb</span><span style="font-family:宋体;">，</span><span style="font-family:Calibri;">_bootstrap_pagetables</span><span style="font-family:宋体;">是内核启动时用到的临时页表。</span></span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W2, </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">#3</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W3, </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">#1</span></p><p><span style="font-family:Calibri;font-size:14px;">BL              _pmap_set_range_xprr_perm ;</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">将</span><span style="font-family:Calibri;">_BootArgs</span><span style="font-family:宋体;">从</span><span style="font-family:Calibri;">0x3</span><span style="font-family:宋体;">设置为</span><span style="font-family:Calibri;">0x1</span><span style="font-family:宋体;">，</span><span style="font-family:Calibri;">_BootArgs</span><span style="font-family:宋体;">是</span><span style="font-family:Calibri;">iboot</span><span style="font-family:宋体;">加载内核时传给内核的参数。</span></span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W2, </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">#0x</span><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:Calibri;">3</span></span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W3, </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">#</span><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:Calibri;">1</span></span></p><p><span style="font-family:Calibri;font-size:14px;">BL              _pmap_set_range_xprr_perm ;</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">将</span><span style="font-family:Calibri;">_segPPLDATAB</span><span style="font-family:宋体;">从</span><span style="font-family:Calibri;">0x3</span><span style="font-family:宋体;">设置为</span><span style="font-family:Calibri;">0x1</span><span style="font-family:宋体;">，</span><span style="font-family:Calibri;">_segPPLDATAB</span><span style="font-family:宋体;">为</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">data</span><span style="font-family:宋体;">段。</span></span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W2, </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">#</span><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:Calibri;">0xA</span></span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W3, </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">#</span><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:Calibri;">0x8</span></span></p><p><span style="font-family:Calibri;font-size:14px;">BL              _pmap_set_range_xprr_perm ;</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">将</span><span style="font-family:Calibri;">_segPPLTEXTB</span><span style="font-family:宋体;">从</span><span style="font-family:Calibri;">0xA</span><span style="font-family:宋体;">设置为</span><span style="font-family:Calibri;">0x8</span><span style="font-family:宋体;">，</span><span style="font-family:Calibri;">_segPPLTEXTB</span><span style="font-family:宋体;">为</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">text</span><span style="font-family:宋体;">段。</span></span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W2, </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">#</span><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:Calibri;">0xB</span></span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W3, </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">#</span><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:Calibri;">0xB</span></span></p><p><span style="font-family:Calibri;font-size:14px;">BL              _pmap_set_range_xprr_perm ;</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">将</span><span style="font-family:Calibri;">_segPPLDATACONSTB</span><span style="font-family:宋体;">从</span><span style="font-family:Calibri;">0xB</span><span style="font-family:宋体;">设置为</span><span style="font-family:Calibri;">0xB</span><span style="font-family:宋体;">，</span><span style="font-family:Calibri;">_segPPLDATACONSTB</span><span style="font-family:宋体;">为</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">dataconst</span><span style="font-family:宋体;">段。</span></span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W2, </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">#</span><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:Calibri;">0x1</span></span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W3, </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">#</span><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:Calibri;">0xB</span></span></p><p><span style="font-family:Calibri;font-size:14px;">BL              _pmap_set_range_xprr_perm ;</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">将</span><span style="font-family:Calibri;">_pmap_stacks_start_pa</span><span style="font-family:宋体;">从</span><span style="font-family:Calibri;">0x1</span><span style="font-family:宋体;">设置为</span><span style="font-family:Calibri;">0xB</span><span style="font-family:宋体;">， </span><span style="font-family:Calibri;">_pmap_stacks_start_pa</span><span style="font-family:宋体;">为</span><span style="font-family:Calibri;">ppl</span><span style="font-family:宋体;">使用的</span><span style="font-family:Calibri;">stack</span><span style="font-family:宋体;">区域。</span></span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,0,0);background:rgb(255,0,0);">_pmap_ledger_alloc_internal</span><span style="font-family:宋体;font-size:14px;background:rgb(255,0,0);background:rgb(255,0,0);"><span style="font-family:Calibri;">:</span></span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W2, </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">#1</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W3, </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">#3</span></p><p><span style="font-family:Calibri;font-size:14px;">BL              _pmap_set_range_xprr_perm ;</span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,0,0);background:rgb(255,0,0);">_pmap_load_image4_trust_cache_internal</span><span style="font-family:宋体;font-size:14px;background:rgb(255,0,0);background:rgb(255,0,0);"><span style="font-family:Calibri;">:</span></span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W2, </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">#0xB</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W3, </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">#1</span></p><p><span style="font-family:Calibri;font-size:14px;">BL              _pmap_set_range_xprr_perm</span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W2, </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">#1</span></p><p><span style="font-family:Calibri;font-size:14px;">MOV             W3, </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">#0xB</span></p><p><span style="font-family:Calibri;font-size:14px;">BL              _pmap_set_range_xprr_perm</span></p><p><span style="font-family:Calibri;font-size:14px;"><br/></span></p><h2 style="margin-left:0;text-indent:0;"><span style="font-family:Arial;font-size:21px;">3.2 </span><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">_pmap_release_ppl_pages_to_kernel_internal</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">它与</span><span style="font-family:Calibri;">_pmap_mark_page_as_ppl_page_internal</span><span style="font-family:宋体;">是一个相反的操作，读者朋友可以自行阅读相关代码。</span></span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><br/></p>



<p><a href="2247483759">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=96a4fedb&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg4NjU1NDU4MA%3D%3D%26mid%3D2247483759%26idx%3D1%26sn%3D766e80eef7692c896c6cbae7c6776981%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Fri, 26 Nov 2021 11:29:00 +0800</pubDate>
    </item>
    <item>
      <title>sel4微内核安全功能解读</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg4NjU1NDU4MA==&amp;mid=2247483746&amp;idx=1&amp;sn=a520c82d3861775adfd4caef028ba79d</link>
      <description>Sel4是l4微内核家族中的一员，se代表security的意思，它采用了形式化验证的手段确保了源码的安全性.</description>
      <content:encoded><![CDATA[<p>
原创 <span>wzt</span> <span>2021-05-31 16:44</span> <span style="display: inline-block;"></span>
</p>

<p>Sel4是l4微内核家族中的一员，se代表security的意思，它采用了形式化验证的手段确保了源码的安全性.</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=dd2d2784&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F4iaJia7Cvd3PAJBTCiawnOm23Tqag56aTS0icCibJC5RtBSRUdjAjaTwZM12DwJf1ssF40QLVx4TbksxECcao6YhFyw%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<p style="margin-top:0;margin-right:0;margin-bottom:0;margin-left:0;text-indent:0;text-align:center;"><br/></p><p><strong style="font-size: 16px;"><span style="font-family: 宋体;font-size: 32px;">1 简介</span></strong><br/></p><p><span style="font-family:宋体;font-size:14px;">    <span style="font-family:Calibri;">Sel4</span><span style="font-family:宋体;">是</span><span style="font-family:Calibri;">l4</span><span style="font-family:宋体;">微内核家族中的一员，</span><span style="font-family:Calibri;">se</span><span style="font-family:宋体;">代表</span><span style="font-family:Calibri;">security</span><span style="font-family:宋体;">的意思，它采用了形式化验证的手段确保了源码的安全性，大概是对形式化验证有很足的信心，</span><span style="font-family:Calibri;">sel4</span><span style="font-family:宋体;">没有使用任何漏洞利用缓解措施，仅仅使用了</span><span style="font-family:Calibri;">intel cpu</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">smep/smap</span><span style="font-family:宋体;">功能。</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h1><strong><span style="font-family: 宋体;font-size: 32px;">2 安全功能</span></strong></h1><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">2.1 kaslr</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">现在的内核地址随机化不止包含内核代码段地址随机化，</span> <span style="font-family:宋体;">还包括了内核自身页表、内核的堆等等。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h3><strong><span style="font-family:宋体;font-size:21px;"><span style="font-family:Calibri;">2.1.1 </span><span style="font-family:宋体;">内核代码段地址随机化</span></span></strong></h3><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">Sel4</span><span style="font-family:宋体;">内核并没有支持内核地址随机化， 以下</span><span style="font-family:Calibri;">x86</span><span style="font-family:宋体;">架构为例：</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">src/arch/x86/64/head.S</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">追踪</span><span style="font-family:Calibri;">sel4</span><span style="font-family:宋体;">内核的启动代码</span><span style="font-family:Calibri;">: _start-&gt;_start64-&gt;_entry_64-&gt;boot_sys-&gt;try_boot_sys:</span></span></p><p><span style="font-family:Calibri;font-size:14px;">static BOOT_CODE bool_t try_boot_sys(void)</span></p><p><span style="font-family:Calibri;font-size:14px;">{</span></p><p><span style="font-family:Calibri;font-size:14px;">    </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">boot_state.ki_p_reg.start = KERNEL_ELF_PADDR_BASE</span><span style="font-family:Calibri;font-size:14px;">;</span></p><p><span style="font-family:Calibri;font-size:14px;">    boot_state.ki_p_reg.end = kpptr_to_paddr(ki_end);</span></p><p><span style="font-family:宋体;font-size:14px;"> </span></p><p><span style="font-family:宋体;font-size:14px;">    <span style="font-family:Calibri;">printf(&#34;Kernel loaded to: start=0x%lx end=0x%lx size=0x%lx entry=0x%lx\n&#34;,</span></span></p><p><span style="font-family:宋体;font-size:14px;">           <span style="font-family:Calibri;">boot_state.ki_p_reg.start,</span></span></p><p><span style="font-family:宋体;font-size:14px;">           <span style="font-family:Calibri;">boot_state.ki_p_reg.end,</span></span></p><p><span style="font-family:宋体;font-size:14px;">           <span style="font-family:Calibri;">boot_state.ki_p_reg.end - boot_state.ki_p_reg.start,</span></span></p><p><span style="font-family:宋体;font-size:14px;">           <span style="font-family:Calibri;">(paddr_t)_start</span></span></p><p><span style="font-family:宋体;font-size:14px;">          <span style="font-family:Calibri;">);</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">}</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">后续的加载地址直接设置为了固定地址。</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><br/></span></p><h3><strong><span style="font-family:宋体;font-size:21px;"><span style="font-family:Calibri;">2.1.2 </span><span style="font-family:宋体;">内核页表地址随机化</span></span></strong></h3><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">在商用</span><span style="font-family:Calibri;">os</span><span style="font-family:宋体;">系统里了，</span><span style="font-family:Calibri;">windows nt</span><span style="font-family:宋体;">内核首先将内核页表做了地址随机化处理，</span><span style="font-family:Calibri;">linux</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">xnu</span><span style="font-family:宋体;">都没有实现。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">Sel4</span><span style="font-family:宋体;">内核也同样没有实现。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">2.2 aslr</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">进程栈地址未使用地址随机化</span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">seL4_libs/libsel4utils/src</span></span></p><p><span style="font-family:Calibri;font-size:14px;">int sel4utils_spawn_process(sel4utils_process_t *process, vka_t *vka, vspace_t *vspace, int argc,</span></p><p><span style="font-family:Calibri;font-size:14px;">                            char *argv[], int resume)</span></p><p><span style="font-family:Calibri;font-size:14px;">{</span></p><p><span style="font-family:宋体;font-size:14px;">     <span style="font-family:Calibri;">uintptr_t initial_stack_pointer = (uintptr_t)process-&gt;thread.stack_top - sizeof(seL4_Word);</span></span></p><p><strong><span style="font-family: Calibri;font-size: 14px;">    </span></strong><strong><span style="font-family: 宋体;font-size: 14px;"> </span></strong><span style="font-family: Calibri;font-size: 14px;">process-&gt;thread.initial_stack_pointer = (void *) initial_stack_pointer;</span></p><p><span style="font-family: 宋体;font-size: 14px;"><span style="font-family:Calibri;">}</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">thread.stack_top</span><span style="font-family:宋体;">地址通过</span></span><span style="font-family: Calibri;font-size: 14px;">sel4utils_reserve_range_aligned</span><span style="font-family: 宋体;font-size: 14px;">函数分配，此函数未使用任何随机化算法。</span></p><p style="text-indent:28px;"><span style="font-family: 宋体;font-size: 14px;">代码段未使用地址随机化</span></p><p><span style="font-family: Calibri;font-size: 14px;">seL4_libs/libsel4utils/src</span></p><p style="text-indent:28px;"><span style="font-family: Calibri;font-size: 14px;">load_segment</span><span style="font-family: 宋体;font-size: 14px;">函数对任何代码段地址都未使用地址随机化算法。</span></p><p style="text-indent:28px;"><span style="font-family: 宋体;font-size: 14px;"><br/></span></p><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">2.3 heap</span></span></strong></h2><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">seL4_libs/libsel4allocman/src</span><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:Calibri;">/allocman.c</span></span></p><p><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:Calibri;">- </span><span style="font-family:宋体;">未提供</span><span style="font-family:Calibri;">redzone</span><span style="font-family:宋体;">，不可检测</span><span style="font-family:Calibri;">overflow</span><span style="font-family:宋体;">。</span></span></p><p><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:Calibri;">- </span><span style="font-family:宋体;">未提供</span><span style="font-family:Calibri;">poison</span><span style="font-family:宋体;">，不可检测</span><span style="font-family:Calibri;">UAF</span><span style="font-family:宋体;">。</span></span></p><p><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:Calibri;">- </span><span style="font-family:宋体;">不可检测</span><span style="font-family:Calibri;">double free</span><span style="font-family:宋体;">。</span></span></p><p><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:Calibri;">- </span><span style="font-family:宋体;">未提供双向链表的安全删除操作。</span></span></p><p><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:Calibri;">- </span><span style="font-family:宋体;">未提供初始化</span><span style="font-family:Calibri;">chunk</span><span style="font-family:宋体;">随机化功能。</span></span></p><p><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:Calibri;">- </span><span style="font-family:宋体;">未提供</span><span style="font-family:Calibri;">cookie</span><span style="font-family:宋体;">完整性验证功能。</span></span></p><p><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:Calibri;">- </span><span style="font-family:宋体;">未提供地址混淆功能。</span></span></p><p><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"> </span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">seL4_libs/libsel4utils/src</span><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:Calibri;">/slab.c</span></span></p><p><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:Calibri;">- </span><span style="font-family:宋体;">未提供</span><span style="font-family:Calibri;">redzone</span><span style="font-family:宋体;">，不可检测</span><span style="font-family:Calibri;">overflow</span><span style="font-family:宋体;">。</span></span></p><p><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:Calibri;">- </span><span style="font-family:宋体;">未提供</span><span style="font-family:Calibri;">poison</span><span style="font-family:宋体;">，不可检测</span><span style="font-family:Calibri;">UAF</span><span style="font-family:宋体;">。</span></span></p><p><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:Calibri;">- </span><span style="font-family:宋体;">不可检测</span><span style="font-family:Calibri;">double free</span><span style="font-family:宋体;">。</span></span></p><p><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:Calibri;">- </span><span style="font-family:宋体;">未提供双向链表的安全删除操作。</span></span></p><p><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:Calibri;">- </span><span style="font-family:宋体;">未提供初始化</span><span style="font-family:Calibri;">chunk</span><span style="font-family:宋体;">随机化功能。</span></span></p><p><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:Calibri;">- </span><span style="font-family:宋体;">未提供</span><span style="font-family:Calibri;">cookie</span><span style="font-family:宋体;">完整性验证功能。</span></span></p><p><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:Calibri;">- </span><span style="font-family:宋体;">未提供地址混淆功能。</span></span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"> </span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><br/></span></p><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">2.4 </span><span style="font-family:黑体;">系统调用过滤</span></span></strong></h2><p><span style="font-family:宋体;font-size:14px;">   <span style="font-family:Calibri;">Sel4</span><span style="font-family:宋体;">系统没有提供系统调用审计和过滤的功能，因为</span><span style="font-family:Calibri;">sel4</span><span style="font-family:宋体;">目前只支持几下几个系统调用：</span></span></p><p><span style="font-family:Calibri;font-size:14px;">seL4/src/api/syscall.c</span><span style="font-family:宋体;font-size:14px;">：</span></p><p><span style="font-family:Calibri;font-size:14px;">exception_t handleSyscall(syscall_t syscall)</span></p><p><span style="font-family:Calibri;font-size:14px;">{</span></p><p><span style="font-family:Calibri;font-size:14px;">        switch (syscall)</span></p><p><span style="font-family:Calibri;font-size:14px;">        {</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">        case SysSend:</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">        case SysNBSend:</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">        case SysCall:</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">        case SysRecv:</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">        case SysReply:</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">        case SysReplyRecv:</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">        case SysWait:</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">        case SysNBWait:</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">        case SysReplyRecv: {</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">        case SysNBSendRecv: {</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">        case SysNBSendWait:</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">        case SysNBRecv:</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">        case SysYield:</span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">}</span></span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">2.5 NULL Page Protection</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">Sel4</span><span style="font-family:宋体;">在提供的</span><span style="font-family:Calibri;">mmap</span><span style="font-family:宋体;">接口中，没有禁止映射内存</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">的限制，而这个功能在</span><span style="font-family:Calibri;">linux</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">NT</span><span style="font-family:宋体;">内核中都做了限制。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">libsel4muslcsys/src/sys_morecore.c</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">mmap</span><span style="font-family:宋体;">的主体函数中没有对</span><span style="font-family:Calibri;">addr</span><span style="font-family:宋体;">地址做限制。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">2.6 mmap/mprotect w^x</span><span style="font-family:黑体;">保护</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">同上，</span> <span style="font-family:Calibri;">mmap/mprtect</span><span style="font-family:宋体;">接口中没有对可写、可执行权限做限制， </span><span style="font-family:Calibri;">linux</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">xnu</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">nt</span><span style="font-family:宋体;">都实现了此保护功能。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">2.7 kernel/module rwx</span><span style="font-family:黑体;">保护</span></span></strong></h2><p><span style="font-family:宋体;font-size:14px;">   <span style="font-family:Calibri;">Sel4</span><span style="font-family:宋体;">内核在启动之初调用</span></span><span style="font-family:Calibri;font-size:14px;">setup_pml4</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">函数对内核代码段的属性设置为</span><span style="font-family:Calibri;">rwx</span><span style="font-family:宋体;">，而在后续直到内核启动完毕，仍没有将</span><span style="font-family:Calibri;">w</span><span style="font-family:宋体;">可写属性去掉，将会把内核暴露为一个可写的危险环境。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">src/arch/x86/64/head.S</span></p><p><span style="font-family:Calibri;font-size:14px;">BEGIN_FUNC(setup_pml4)</span></p><p><span style="font-family:Calibri;font-size:14px;">    movl $_boot_pd, %ecx</span></p><p><span style="font-family:Calibri;font-size:14px;">    </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">orl  $0x7, %ecx</span></p><p><span style="font-family:Calibri;font-size:14px;">    movl $boot_pdpt, %edi</span></p><p><span style="font-family:Calibri;font-size:14px;">    movl %ecx, (%edi)</span></p><p><span style="font-family:Calibri;font-size:14px;">    movl %ecx, 4080(%edi)</span></p><p><span style="font-family:Calibri;font-size:14px;">    addl $0x1000, %ecx</span></p><p><span style="font-family:Calibri;font-size:14px;">    movl %ecx, 8(%edi)</span></p><p><span style="font-family:Calibri;font-size:14px;">    addl $0x1000, %ecx</span></p><p><span style="font-family:Calibri;font-size:14px;">    movl %ecx, 16(%edi)</span></p><p><span style="font-family:Calibri;font-size:14px;">    addl $0x1000, %ecx</span></p><p><span style="font-family:Calibri;font-size:14px;">    movl %ecx, 24(%edi)</span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;">Ret</span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;"><br/></span></p><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">2.8 cpu SMEP/SMAP</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">Sel4</span><span style="font-family:宋体;">内核提供了</span><span style="font-family:Calibri;">cpu smep/smap</span><span style="font-family:宋体;">功能：</span></span></p><p><span style="font-family:Calibri;font-size:14px;">seL4/src/arch/x86/kernel/boot.c</span><span style="font-family:宋体;font-size:14px;">：</span></p><p><span style="font-family:Calibri;font-size:14px;">BOOT_CODE bool_t init_cpu(</span></p><p><span style="font-family:Calibri;font-size:14px;">    bool_t   mask_legacy_irqs</span></p><p><span style="font-family:Calibri;font-size:14px;">)</span></p><p><span style="font-family:Calibri;font-size:14px;">{</span></p><p><span style="font-family:Calibri;font-size:14px;">    if (cpuid_007h_ebx_get_smap(ebx_007)) {</span></p><p><span style="font-family:Calibri;font-size:14px;">        if (!config_set(CONFIG_PRINTING) &amp;&amp; !config_set(CONFIG_DANGEROUS_CODE_INJECTION)) {</span></p><p><span style="font-family:Calibri;font-size:14px;">            </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">write_cr4(read_cr4() | CR4_SMAP);</span></p><p><span style="font-family:Calibri;font-size:14px;">        }</span></p><p><span style="font-family:Calibri;font-size:14px;">    }</span></p><p><span style="font-family:Calibri;font-size:14px;">    if (cpuid_007h_ebx_get_smep(ebx_007)) {</span></p><p><span style="font-family:Calibri;font-size:14px;">        if (!config_set(CONFIG_DANGEROUS_CODE_INJECTION)) {</span></p><p><span style="font-family:Calibri;font-size:14px;">            </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">write_cr4(read_cr4() | CR4_SMEP);</span></p><p><span style="font-family:Calibri;font-size:14px;">        }</span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;">}</span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">}</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;"><br/></span></span></p><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">2.9 intel spectre v1</span><span style="font-family:黑体;">漏洞缓解</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">Sel4</span><span style="font-family:宋体;">未提供</span><span style="font-family:Calibri;">intel cpu spectre v1</span><span style="font-family:宋体;">漏洞类型的缓解机制：</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">src/arch/x86/64/traps.S</span><span style="font-family:宋体;">：</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">#define MAYBE_SWAPGS swapgs</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">BEGIN_FUNC(handle_syscall)</span></span></p><p><span style="font-family:宋体;font-size:14px;">    <span style="font-family:Calibri;">LOAD_KERNEL_AS(rsp)</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><span style="font-family:Calibri;">MAYBE_SWAPGS</span></span></p><p><span style="font-family:宋体;font-size:14px;">    <span style="font-family:Calibri;">push    %r11</span></span></p><p><span style="font-family:宋体;font-size:14px;">    <span style="font-family:Calibri;">push    %rdx            # save FaultIP</span></span></p><p><span style="font-family:宋体;font-size:14px;">    <span style="font-family:Calibri;">push    %rcx            # save RSP</span></span></p><p><span style="font-family:宋体;font-size:14px;"> </span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">Swap</span><span style="font-family:宋体;">指令后并没有</span><span style="font-family:Calibri;">lfence</span><span style="font-family:宋体;">指令做序列化保护，</span><span style="font-family:Calibri;">cpu</span><span style="font-family:宋体;">指令预测执行可绕过</span><span style="font-family:Calibri;">swapgs</span><span style="font-family:宋体;">指令。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">2.10 intel spectre v2</span><span style="font-family:黑体;">漏洞缓解</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">Sel4</span><span style="font-family:宋体;">未提供</span><span style="font-family:Calibri;">intel cpu spectre v2</span><span style="font-family:宋体;">漏洞类型的缓解机制：</span></span></p><p><span style="font-family:Calibri;font-size:14px;">src/arch/x86/64/head.S</span></p><p><span style="font-family:Calibri;font-size:14px;">BEGIN_FUNC(_start64)</span></p><p><span style="font-family:Calibri;font-size:14px;">    movabs $_entry_64, %rax</span></p><p><span style="font-family:Calibri;font-size:14px;">    </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">jmp *%rax</span></p><p><span style="font-family:Calibri;font-size:14px;">END_FUNC(_start64)</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">缺少</span><span style="font-family:Calibri;">return trampline</span><span style="font-family:宋体;">的指令段转换。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">2.11 shadow stack</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">未提供</span><span style="font-family:Calibri;">shadow stack</span><span style="font-family:宋体;">保护。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">2.12 CFI</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">未提供</span><span style="font-family:Calibri;">CFI</span><span style="font-family:宋体;">保护</span><span style="font-family:Calibri;">.</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;"><br/></span></span></p><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">2.13 PAC</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">未提供</span><span style="font-family:Calibri;">PAC</span><span style="font-family:宋体;">保护。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">2.14 Code sign</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">未提供代码签名保护。</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><br/></span></p><h1><strong><span style="font-family: 宋体;font-size: 32px;">3 关于形式化验证</span></strong></h1><p><span style="font-family:宋体;font-size:14px;">    <span style="font-family:宋体;">由于</span><span style="font-family:Calibri;">c</span><span style="font-family:宋体;">语言的语法复杂和灵活，形式化验证手段要将</span><span style="font-family:Calibri;">c</span><span style="font-family:宋体;">语言转化为一个能够被数学逻辑验证的语言。这个语言要依赖一些威胁模型，这些模型源自于对内核行为的一些预测。如果威胁模型在构建的时候就忽略了一些条件和情况外，那么这个形式化验证就不够全面。这个威胁模型完全取决于人的经验，如果人的经验不足，就会漏掉很多模型。举个例子，给</span><span style="font-family:Calibri;">stack smashing</span><span style="font-family:宋体;">做威胁模型，如果程序员只知道</span><span style="font-family:Calibri;">overflow</span><span style="font-family:宋体;">会覆盖</span><span style="font-family:Calibri;">return address</span><span style="font-family:宋体;">才叫漏洞的话，那么就会漏掉函数指针覆盖这种情况，它同样会改变程序的执行流程。笔者始终认为一个好的商用微内核系统，除了使用形式化验证外，基本的漏洞利用缓解措施还是有必要加上的。</span></span></p><p><br/></p>



<p><a href="2247483746">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=2e6b36f4&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg4NjU1NDU4MA%3D%3D%26mid%3D2247483746%26idx%3D1%26sn%3Da520c82d3861775adfd4caef028ba79d%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Mon, 31 May 2021 16:44:00 +0800</pubDate>
    </item>
    <item>
      <title>fuchsia安全功能解读</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg4NjU1NDU4MA==&amp;mid=2247483741&amp;idx=1&amp;sn=d988a8bab992c17a189461b08ec6a2e6</link>
      <description>1 简介Fuchsia是google开发的全新微内核操作系统，用来替换android。</description>
      <content:encoded><![CDATA[<p>
原创 <span>wzt</span> <span>2021-05-29 13:24</span> <span style="display: inline-block;"></span>
</p>

<p>1 简介Fuchsia是google开发的全新微内核操作系统，用来替换android。</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=69d69f1e&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F4iaJia7Cvd3PAredOW79DmDZ1x3R17Ce2rUic1CLzdR3bbvl5zX8REHHqKnUVeibKfxZlCknX8eY58mQQ2ibZozC3CA%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<h1><strong><span style="font-family:宋体;font-size:29px;"><span style="font-family:Calibri;">1 </span><span style="font-family:宋体;">简介</span></span></strong></h1><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">Fuchsia</span><span style="font-family:宋体;">是</span><span style="font-family:Calibri;">google</span><span style="font-family:宋体;">开发的全新微内核操作系统，用来替换</span><span style="font-family:Calibri;">android</span><span style="font-family:宋体;">。本文根据</span><span style="font-family:Calibri;">fuchsia</span><span style="font-family:宋体;">最新的官方代码，来分析它所提供的一些安全功能。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h1><strong><span style="font-family:宋体;font-size:29px;"><span style="font-family:Calibri;">2 </span><span style="font-family:宋体;">安全功能</span></span></strong></h1><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">2.1 kaslr</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">现在的内核地址随机化不止包含内核代码段地址随机化，</span> <span style="font-family:宋体;">还包括了内核自身页表、内核的堆等等。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h3><strong><span style="font-family:宋体;font-size:21px;"><span style="font-family:Calibri;">2.1.1 </span><span style="font-family:宋体;">内核代码段地址随机化</span></span></strong></h3><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">zircon</span><span style="font-family:宋体;">内核并没有支持内核地址随机化， 以</span><span style="font-family:Calibri;">aarch64</span><span style="font-family:宋体;">为例：</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">zircon/kernel/arch/arm64/start.S:</span></span></p><p><span style="font-family:Calibri;font-size:14px;">    adr_global  tmp, </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">kernel_relocated_base</span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;">ldr     kernel_vaddr, [tmp]</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">Kernel_relocated_base</span><span style="font-family:宋体;">符号保存着内核实际的加载地址，定义在：</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">zircon/kernel/arch/arm64/mmu.cc</span><span style="font-family:宋体;">：</span></span></p><p><span style="font-family:Calibri;font-size:14px;">#if DISABLE_KASLR</span></p><p><span style="font-family:Calibri;font-size:14px;">uint64_t kernel_relocated_base = KERNEL_BASE;</span></p><p><span style="font-family:Calibri;font-size:14px;">#else</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">uint64_t kernel_relocated_base = 0xffffffff10000000;</span></p><p><span style="font-family:Calibri;font-size:14px;">#endif</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">可以看到，当前是一个固定的值，注释也强调了未来会使用随机化。</span></p><p><span style="font-family:Calibri;font-size:14px;">// Static relocated base to prepare for KASLR. Used at early boot and by gdb</span></p><p><span style="font-family:Calibri;font-size:14px;">// script to know the target relocated address.</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,0,0);background:rgb(255,0,0);">// TODO(fxbug.dev/24762): Choose it randomly.</span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">X86</span><span style="font-family:宋体;">架构同样没有实现：</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">zircon/kernel/arch/x86/mmu.cc</span></span></p><p><span style="font-family:Calibri;font-size:14px;">// Static relocated base to prepare for KASLR. Used at early boot and by gdb</span></p><p><span style="font-family:Calibri;font-size:14px;">// script to know the target relocated address.</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,0,0);background:rgb(255,0,0);">// TODO(thgarnie): Move to a dynamically generated base address</span></p><p><span style="font-family:Calibri;font-size:14px;">#if DISABLE_KASLR</span></p><p><span style="font-family:Calibri;font-size:14px;">uint64_t kernel_relocated_base = KERNEL_BASE - KERNEL_LOAD_OFFSET;</span></p><p><span style="font-family:Calibri;font-size:14px;">#else</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">uint64_t kernel_relocated_base = 0xffffffff00000000;</span></p><p><span style="font-family:Calibri;font-size:14px;">#endif</span></p><p><span style="font-family:Calibri;font-size:14px;"><br/></span></p><h3><strong><span style="font-family:宋体;font-size:21px;"><span style="font-family:Calibri;">2.1.2 </span><span style="font-family:宋体;">内核页表地址随机化</span></span></strong></h3><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">在商用</span><span style="font-family:Calibri;">os</span><span style="font-family:宋体;">系统里了，</span><span style="font-family:Calibri;">windows nt</span><span style="font-family:宋体;">内核首先将内核页表做了地址随机化处理，</span><span style="font-family:Calibri;">linux</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">xnu</span><span style="font-family:宋体;">都没有实现。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">zircon</span><span style="font-family:宋体;">内核也同样没有实现。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">zircon/kernel/arch/arm64/mmu.cc</span></p><p><span style="font-family:Calibri;font-size:14px;">// The main translation table for the kernel. Globally declared because it&#39;s reached</span></p><p><span style="font-family:Calibri;font-size:14px;">// from assembly.</span></p><p><span style="font-family:Calibri;font-size:14px;">pte_t arm64_kernel_translation_table[MMU_KERNEL_PAGE_TABLE_ETRIES_TOP] __ALIGNED(</span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;">MMU_KERNEL_PAGE_TABLE_ENTRIES_TOP * 8);</span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;"><br/></span></p><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">2.2 aslr</span></span></strong></h2><p><span style="font-family:宋体;font-size:14px;">   <span style="font-family:Calibri;">Fuchsia</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">stack</span><span style="font-family:宋体;">、代码段（包含</span><span style="font-family:Calibri;">pie</span><span style="font-family:宋体;">）等等都是通过</span><span style="font-family:Calibri;">zx_vmar_map</span><span style="font-family:宋体;">函数来建立的，这是一个系统调用， </span><span style="font-family:Calibri;">fuchsia</span><span style="font-family:宋体;">的系统调用似乎是自动生成的，笔者对这块的逻辑尚未熟悉，不过在</span><span style="font-family:Calibri;">docs</span><span style="font-family:宋体;">文档里有说明是随机化产生的地址。</span></span></p><p><strong><span style="font-family: 宋体;font-size: 14px;"><span style="font-family:Calibri;">docs/reference/syscalls/vmar_map.md</span><span style="font-family:宋体;">：</span></span></strong></p><p><span style="font-family:Calibri;font-size:14px;">*vmar_offset* must be 0 if *options* does not have **ZX_VM_SPECIFIC** or</span></p><p><span style="font-family:Calibri;font-size:14px;">**ZX_VM_SPECIFIC_OVERWRITE** set.  </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">If neither of those are set, then</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">the mapping will be assigned an offset at random by the kernel (with an</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">allocator determined by policy set on the target VMAR).</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><br/></span></p><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">2.3 code sign</span></span></strong></h2><p><span style="font-family:宋体;font-size:14px;">   <span style="font-family:Calibri;">fuchsia</span><span style="font-family:宋体;">系统没有提供</span><span style="font-family:Calibri;">app</span><span style="font-family:宋体;">证书签名和代码完整性校验的功能。</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">2.4 </span><span style="font-family:黑体;">系统调用过滤</span></span></strong></h2><p><span style="font-family:宋体;font-size:14px;">   <span style="font-family:Calibri;">fuchsia</span><span style="font-family:宋体;">系统没有提供系统调用审计和过滤的功能。</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">zircon/kernel/arch/arm64/exceptions.S</span><span style="font-family:宋体;">：</span></span></p><p><span style="font-family:Calibri;font-size:14px;">LOCAL_FUNCTION_LABEL(arm64_syscall_dispatcher)</span></p><p><span style="font-family:Calibri;font-size:14px;">    start_isr_func_cfi</span></p><p><span style="font-family:Calibri;font-size:14px;">    cmp  x16, #ZX_SYS_COUNT</span></p><p><span style="font-family:Calibri;font-size:14px;">    bhs  .Lunknown_syscall</span></p><p><span style="font-family:Calibri;font-size:14px;">    csel x16, xzr, x16, hs</span></p><p><span style="font-family:Calibri;font-size:14px;">    csdb</span></p><p><span style="font-family:Calibri;font-size:14px;">   </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"> adr  x12, .Lsyscall_table</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">    add  x12, x12, x16, lsl #4</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">    br   x12</span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;">SPECULATION_POSTFENCE</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">在判断系统调用号是否超出范围之后，</span> <span style="font-family:宋体;">直接调用了</span><span style="font-family:Calibri;">syscall_table</span><span style="font-family:宋体;">对应的函数指针。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">没有像</span><span style="font-family:Calibri;">linux</span><span style="font-family:宋体;">提供了</span><span style="font-family:Calibri;">audit</span><span style="font-family:宋体;">系统调用审计和</span><span style="font-family:Calibri;">secomp</span><span style="font-family:宋体;">系统调用过滤的功能。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">X86</span><span style="font-family:宋体;">架构同样如此：</span></span></p><p><span style="font-family:Calibri;font-size:14px;">zircon/kernel/arch/x86/syscall.</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">S</span><span style="font-family:宋体;">：</span></span></p><p><span style="font-family:Calibri;font-size:14px;">.balign 16</span></p><p><span style="font-family:Calibri;font-size:14px;">FUNCTION_LABEL(x86_syscall)</span></p><p><span style="font-family:Calibri;font-size:14px;">    // swap to the kernel GS register</span></p><p><span style="font-family:Calibri;font-size:14px;">    swapgs</span></p><p><span style="font-family:Calibri;font-size:14px;">    // save the user stack pointer</span></p><p><span style="font-family:Calibri;font-size:14px;">    mov     %rsp, %gs:PERCPU_SAVED_USER_SP_OFFSET</span></p><p><span style="font-family:Calibri;font-size:14px;">    // load the kernel stack pointer</span></p><p><span style="font-family:Calibri;font-size:14px;">    mov     %gs:PERCPU_KERNEL_SP_OFFSET, %rsp</span></p><p><span style="font-family:Calibri;font-size:14px;">    .cfi_def_cfa %rsp, 0</span></p><p><span style="font-family:Calibri;font-size:14px;">    push_value %gs:PERCPU_SAVED_USER_SP_OFFSET  // User stack</span></p><p><span style="font-family:Calibri;font-size:14px;">    push_value %r11  // RFLAGS</span></p><p><span style="font-family:Calibri;font-size:14px;">    push_value %rcx  // RIP</span></p><p><span style="font-family:Calibri;font-size:14px;">    push_value %r15</span></p><p><span style="font-family:Calibri;font-size:14px;">    push_value %r14</span></p><p><span style="font-family:Calibri;font-size:14px;">    push_value %r13</span></p><p><span style="font-family:Calibri;font-size:14px;">    push_value %r12</span></p><p><span style="font-family:Calibri;font-size:14px;">    push_value $0    // R11 was trashed by the syscall instruction.</span></p><p><span style="font-family:Calibri;font-size:14px;">    push_value %r10</span></p><p><span style="font-family:Calibri;font-size:14px;">    push_value %r9</span></p><p><span style="font-family:Calibri;font-size:14px;">    push_value %r8</span></p><p><span style="font-family:Calibri;font-size:14px;">    push_value %rbp</span></p><p><span style="font-family:Calibri;font-size:14px;">    push_value %rdi</span></p><p><span style="font-family:Calibri;font-size:14px;">    push_value %rsi</span></p><p><span style="font-family:Calibri;font-size:14px;">    push_value %rdx</span></p><p><span style="font-family:Calibri;font-size:14px;">    push_value $0    // RCX was trashed by the syscall instruction.</span></p><p><span style="font-family:Calibri;font-size:14px;">    push_value %rbx</span></p><p><span style="font-family:Calibri;font-size:14px;">    push_value %rax</span></p><p><span style="font-family:Calibri;font-size:14px;">    cmp     $ZX_SYS_COUNT, %rax</span></p><p><span style="font-family:Calibri;font-size:14px;">    jae     .Lunknown_syscall</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">    leaq    .Lcall_wrapper_table(%rip), %r11</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">    movq    (%r11,%rax,8), %r11</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">    lfence</span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">jmp     *%r11</span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);"><br/></span></p><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">2.5 NULL Page Protection</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">fuchsia</span><span style="font-family:宋体;">在提供的</span><span style="font-family:Calibri;">mmap</span><span style="font-family:宋体;">接口中，没有禁止映射内存</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">的限制，而这个功能在</span><span style="font-family:Calibri;">linux</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">NT</span><span style="font-family:宋体;">内核中都做了限制。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">zircon/third_party/ulib/musl/src/mman/mmap.c</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">mmap</span><span style="font-family:宋体;">的主体函数中没有对</span><span style="font-family:Calibri;">addr</span><span style="font-family:宋体;">地址做限制。</span></span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;"> </span></p><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">2.6 mmap/mprotect w^x</span><span style="font-family:黑体;">保护</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">同上，</span> <span style="font-family:Calibri;">mmap/mprtect</span><span style="font-family:宋体;">接口中没有对可写、可执行权限做限制， </span><span style="font-family:Calibri;">linux</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">xnu</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">nt</span><span style="font-family:宋体;">都实现了此保护功能。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">2.7 printf %K</span><span style="font-family:黑体;">内核地址保护</span></span></strong></h2><p><span style="font-family:宋体;font-size:14px;">   <span style="font-family:Calibri;">Printf</span><span style="font-family:宋体;">未实现</span><span style="font-family:Calibri;">%K</span><span style="font-family:宋体;">内核地址保护功能，利用</span><span style="font-family:Calibri;">%p</span><span style="font-family:宋体;">可能将内核地址泄露出来。</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">zircon/third_party/ulib/musl/src/stdio/vfprintf.c</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;"><br/></span></span></p><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">2.8 Ref counter</span><span style="font-family:黑体;">保护</span></span></strong></h2><p><span style="font-family:宋体;font-size:14px;">   <span style="font-family:Calibri;">Fuchsia</span><span style="font-family:宋体;">未实现类似</span><span style="font-family:Calibri;">linux</span><span style="font-family:宋体;">的引用计数溢出保护。</span></span></p><p><span style="font-family:Calibri;font-size:14px;">zircon/kernel/lib/counters/counters.cc</span></p><p><span style="font-family:Calibri;font-size:14px;"><br/></span></p><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">2.9 kernel/module rwx</span><span style="font-family:黑体;">保护</span></span></strong></h2><p><span style="font-family:宋体;font-size:14px;">   <span style="font-family:Calibri;">zircon</span><span style="font-family:宋体;">内核在启动之出对内核代码段的属性设置为</span><span style="font-family:Calibri;">rwx</span><span style="font-family:宋体;">，在后续的</span><span style="font-family:Calibri;">vm_init</span><span style="font-family:宋体;">中，将内核的代码和数据属性进行了正确设置：</span></span></p><p><span style="font-family:Calibri;font-size:14px;">zircon/kernel/vm/vm.cc</span><span style="font-family:宋体;font-size:14px;">：</span></p><p><span style="font-family:Calibri;font-size:14px;">namespace {</span></p><p><span style="font-family:Calibri;font-size:14px;">const ktl::array _kernel_regions = {</span></p><p><span style="font-family:Calibri;font-size:14px;">    kernel_region{</span></p><p><span style="font-family:Calibri;font-size:14px;">        .name = &#34;</span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">kernel_code</span><span style="font-family:Calibri;font-size:14px;">&#34;,</span></p><p><span style="font-family:Calibri;font-size:14px;">        .base = (vaddr_t)__code_start,</span></p><p><span style="font-family:Calibri;font-size:14px;">        .size = ROUNDUP((uintptr_t)__code_end - (uintptr_t)__code_start, PAGE_SIZE),</span></p><p><span style="font-family:Calibri;font-size:14px;">        .arch_mmu_flags = </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_EXECUTE</span><span style="font-family:Calibri;font-size:14px;">,</span></p><p><span style="font-family:Calibri;font-size:14px;">    },</span></p><p><span style="font-family:Calibri;font-size:14px;">    kernel_region{</span></p><p><span style="font-family:Calibri;font-size:14px;">        .name = &#34;</span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">kernel_rodata</span><span style="font-family:Calibri;font-size:14px;">&#34;,</span></p><p><span style="font-family:Calibri;font-size:14px;">        .base = (vaddr_t)__rodata_start,</span></p><p><span style="font-family:Calibri;font-size:14px;">        .size = ROUNDUP((uintptr_t)__rodata_end - (uintptr_t)__rodata_start, PAGE_SIZE),</span></p><p><span style="font-family:Calibri;font-size:14px;">        .arch_mmu_flags = </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">ARCH_MMU_FLAG_PERM_READ</span><span style="font-family:Calibri;font-size:14px;">,</span></p><p><span style="font-family:Calibri;font-size:14px;">    },</span></p><p><span style="font-family:Calibri;font-size:14px;">    kernel_region{</span></p><p><span style="font-family:Calibri;font-size:14px;">        .name = &#34;</span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">kernel_data</span><span style="font-family:Calibri;font-size:14px;">&#34;,</span></p><p><span style="font-family:Calibri;font-size:14px;">        .base = (vaddr_t)__data_start,</span></p><p><span style="font-family:Calibri;font-size:14px;">        .size = ROUNDUP((uintptr_t)__data_end - (uintptr_t)__data_start, PAGE_SIZE),</span></p><p><span style="font-family:Calibri;font-size:14px;">        .arch_mmu_flags = </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_WRITE</span><span style="font-family:Calibri;font-size:14px;">,</span></p><p><span style="font-family:Calibri;font-size:14px;">    },</span></p><p><span style="font-family:Calibri;font-size:14px;">    kernel_region{</span></p><p><span style="font-family:Calibri;font-size:14px;">        .name = &#34;kernel_bss&#34;,</span></p><p><span style="font-family:Calibri;font-size:14px;">        .base = (vaddr_t)__bss_start,</span></p><p><span style="font-family:Calibri;font-size:14px;">        .size = ROUNDUP((uintptr_t)_end - (uintptr_t)__bss_start, PAGE_SIZE),</span></p><p><span style="font-family:Calibri;font-size:14px;">        .arch_mmu_flags = </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_WRITE</span><span style="font-family:Calibri;font-size:14px;">,</span></p><p><span style="font-family:Calibri;font-size:14px;">    },</span></p><p><span style="font-family:Calibri;font-size:14px;">};</span></p><p><span style="font-family:Calibri;font-size:14px;">}</span></p><p><span style="font-family:Calibri;font-size:14px;"><br/></span></p><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">2.10 kernel stack canary</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">fuchsia</span><span style="font-family:宋体;">使用</span><span style="font-family:Calibri;">clang</span><span style="font-family:宋体;">编译器，默认开启了</span><span style="font-family:Calibri;">fstack-protector</span><span style="font-family:宋体;">参数。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">在启动阶段设置</span><span style="font-family:Calibri;">thread pointer</span><span style="font-family:宋体;">地址时就开始引入了一个随机化的</span><span style="font-family:Calibri;">stack canary</span><span style="font-family:宋体;">值。</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">zircon/kernel/arch/arm64/start.S</span></span></p><p><span style="font-family:Calibri;font-size:14px;">bl      choose_stack_guard</span></p><p><span style="font-family:Calibri;font-size:14px;">zircon/kernel/top/debug.cc</span></p><p><span style="font-family:Calibri;font-size:14px;">__NO_SAFESTACK uintptr_t choose_stack_guard(void) {</span></p><p><span style="font-family:Calibri;font-size:14px;">  uintptr_t guard;</span></p><p><span style="font-family:Calibri;font-size:14px;">  if (hw_rng_get_entropy(&amp;guard, sizeof(guard)) != sizeof(guard)) {</span></p><p><span style="font-family:Calibri;font-size:14px;">    // We can&#39;t get a random value, so use a randomish value.</span></p><p><span style="font-family:Calibri;font-size:14px;">    guard = 0xdeadbeef00ff00ffUL ^ (uintptr_t)&amp;guard;</span></p><p><span style="font-family:Calibri;font-size:14px;">  }</span></p><p><span style="font-family:Calibri;font-size:14px;">  return guard;</span></p><p><span style="font-family:Calibri;font-size:14px;">}</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">以后每个线程在创建的时候，都会使用上述初始化选定的</span><span style="font-family:Calibri;">canary</span><span style="font-family:宋体;">值。</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">zircon/kernel/arch/arm64/thread.cc</span></span></p><p><span style="font-family:Calibri;font-size:14px;">void arch_thread_initialize(Thread* t, vaddr_t entry_point) {</span></p><p><span style="font-family:Calibri;font-size:14px;">  // compiler ABI (TPIDR_EL1 + ZX_TLS_STACK_GUARD_OFFSET).</span></p><p><span style="font-family:Calibri;font-size:14px;">  t-&gt;arch().stack_guard = </span><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">Thread::Current::Get()-&gt;arch().stack_guard</span><span style="font-family:Calibri;font-size:14px;">;</span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:Calibri;font-size:14px;">  // set the stack pointer</span></p><p><span style="font-family:Calibri;font-size:14px;">  t-&gt;arch().sp = (vaddr_t)frame;</span></p><p><span style="font-family:Calibri;font-size:14px;">#if __has_feature(safe_stack)</span></p><p><span style="font-family:Calibri;font-size:14px;">  DEBUG_ASSERT(IS_ALIGNED(t-&gt;stack_.unsafe_top(), 16));</span></p><p><span style="font-family:Calibri;font-size:14px;">  t-&gt;arch().unsafe_sp = t-&gt;stack_.unsafe_top();</span></p><p><span style="font-family:Calibri;font-size:14px;">#endif</span></p><p><span style="font-family:Calibri;font-size:14px;">#if __has_feature(shadow_call_stack)</span></p><p><span style="font-family:Calibri;font-size:14px;">  // The shadow call stack grows up.</span></p><p><span style="font-family:Calibri;font-size:14px;">  t-&gt;arch().shadow_call_sp = reinterpret_cast&lt;uintptr_t*&gt;(t-&gt;stack().shadow_call_base());</span></p><p><span style="font-family:Calibri;font-size:14px;">#endif</span></p><p><span style="font-family:Calibri;font-size:14px;">}</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">所以每个线程使用的</span><span style="font-family:Calibri;">canary</span><span style="font-family:宋体;">值都是同一个， 较</span><span style="font-family:Calibri;">linux</span><span style="font-family:宋体;">每个线程使用不同的值有所弱化。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">2.11 shadow stack</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">fuchsia</span><span style="font-family:宋体;">使用的是</span><span style="font-family:Calibri;">clang</span><span style="font-family:宋体;">编译器，默认使用了</span></span><span style="color: rgb(55, 71, 79);letter-spacing: 0;font-size: 14px;background: rgb(241, 243, 244);">-fsanitize=shadow-call-stack</span><span style="font-family: 宋体;color: rgb(55, 71, 79);letter-spacing: 0;font-size: 14px;background: rgb(241, 243, 244);"><span style="font-family:宋体;">，</span></span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">llvm</span><span style="font-family:宋体;">的官方文档指出仅在</span><span style="font-family:Calibri;">aarch64</span><span style="font-family:宋体;">上实现了</span><span style="font-family:Calibri;">shadow stack</span><span style="font-family:宋体;">的功能，</span><span style="font-family:Calibri;">x86_64</span><span style="font-family:宋体;">上因为一些安全原因将这个功能移除主线代码了。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">Aarch64</span><span style="font-family:宋体;">上，</span><span style="font-family:Calibri;">fuchsia</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">abi</span><span style="font-family:宋体;">约定</span><span style="font-family:Calibri;">x18</span><span style="font-family:宋体;">寄存器保存的是</span><span style="font-family:Calibri;">shadow stack</span><span style="font-family:宋体;">的地址，由于笔者尚未编译完</span><span style="font-family:Calibri;">zircon</span><span style="font-family:宋体;">内核二进制，以下示例来自</span></span><span style="text-decoration:underline;"><span style="font-family: 宋体;color: rgb(0, 0, 255);"><span style="font-family:Calibri;">llvm</span><span style="font-family:宋体;">官方文档</span></span></span><span style="font-family:宋体;font-size:14px;">。</span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">int foo() {</span></span></p><p><span style="font-family:宋体;font-size:14px;">  <span style="font-family:Calibri;">return bar() + 1;</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">}</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">不开启</span><span style="font-family:Calibri;">shadow stack:</span></span></p><p><span style="font-family:Calibri;font-size:14px;">stp     x29, x30, [sp, #-16]!</span></p><p><span style="font-family:Calibri;font-size:14px;">mov     x29, sp</span></p><p><span style="font-family:Calibri;font-size:14px;">bl      bar</span></p><p><span style="font-family:Calibri;font-size:14px;">add     w0, w0, #1</span></p><p><span style="font-family:Calibri;font-size:14px;">ldp     x29, x30, [sp], #16</span></p><p><span style="font-family:Calibri;font-size:14px;">Ret</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">开启后：</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">str     x30, [x18], #8</span></p><p><span style="font-family:Calibri;font-size:14px;">stp     x29, x30, [sp, #-16]!</span></p><p><span style="font-family:Calibri;font-size:14px;">mov     x29, sp</span></p><p><span style="font-family:Calibri;font-size:14px;">bl      bar</span></p><p><span style="font-family:Calibri;font-size:14px;">add     w0, w0, #1</span></p><p><span style="font-family:Calibri;font-size:14px;">ldp     x29, x30, [sp], #16</span></p><p><span style="font-family:Calibri;font-size:14px;background:rgb(255,255,0);background:rgb(255,255,0);">ldr     x30, [x18, #-8]!</span></p><p><span style="font-family:Calibri;font-size:14px;">ret</span></p><p><span style="font-family:Calibri;font-size:14px;"><br/></span></p><h2><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">2.12 safe stack</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">Safe stack</span><span style="font-family:宋体;">与</span><span style="font-family:Calibri;">shadow stack</span><span style="font-family:宋体;">功能非常相近，使用</span><span style="font-family:Calibri;">-fsanitize=safe-stack</span><span style="font-family:宋体;">参数编译。</span><span style="font-family:Calibri;">Shadow stack</span><span style="font-family:宋体;">仅仅保存函数的返回地址，而</span><span style="font-family:Calibri;">safe stack</span><span style="font-family:宋体;">除了保存返回地址外，一些寄存器值和局部变量的值也会保存。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">在</span><span style="font-family:Calibri;">shadow stack</span><span style="font-family:宋体;">中， </span><span style="font-family:Calibri;">sp</span><span style="font-family:宋体;">保存的是</span><span style="font-family:Calibri;">shadow stack</span><span style="font-family:宋体;">的地址，</span><span style="font-family:Calibri;">x18</span><span style="font-family:宋体;">寄存器保存的是正常</span><span style="font-family:Calibri;">stack</span><span style="font-family:宋体;">的地址。而在</span><span style="font-family:Calibri;">safe stack</span><span style="font-family:宋体;">中，</span><span style="font-family:Calibri;">sp</span><span style="font-family:宋体;">保存的是</span><span style="font-family:Calibri;">safe stack</span><span style="font-family:宋体;">的地址，而</span><span style="font-family:Calibri;">unsafe stack</span><span style="font-family:宋体;">的地址是保存在</span><span style="font-family:Calibri;">fs</span><span style="font-family:宋体;">或</span><span style="font-family:Calibri;">gs</span><span style="font-family:宋体;">寄存器的某个固定偏移中。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">X86_64:  </span></span><span style="font-family:Calibri;font-size:14px;">%gs:ZX_TLS_UNSAFE_SP_OFFSET</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">Aarch64:  __builtin_thread_pointer()</span><span style="font-family:宋体;">或者</span><span style="font-family:Calibri;">TPIDR_EL0/1</span></span></p><p><br/></p>



<p><a href="2247483741">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=c61e3639&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg4NjU1NDU4MA%3D%3D%26mid%3D2247483741%26idx%3D1%26sn%3Dd988a8bab992c17a189461b08ec6a2e6%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Sat, 29 May 2021 13:24:00 +0800</pubDate>
    </item>
    <item>
      <title>IOS13 zone_require原理</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg4NjU1NDU4MA==&amp;mid=2247483736&amp;idx=1&amp;sn=abe13c27f4187bfcc199288c59e7c17e</link>
      <description>Ios13增加了判断对象是否属于zone的安全检查，这将导致以前通过伪造内核对象的漏洞利用手段变得困难了</description>
      <content:encoded><![CDATA[<p>
原创 <span>wzt</span> <span>2021-02-23 11:25</span> <span style="display: inline-block;"></span>
</p>

<p>Ios13增加了判断对象是否属于zone的安全检查，这将导致以前通过伪造内核对象的漏洞利用手段变得困难了</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=bfcea4aa&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F4iaJia7Cvd3PCandLM8NNGw2yojdWzPgy4ANSG922CvTlrCcribUOptHCtM52yDG97iayHrPjfibxWds1qopeQsl8fA%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<p><span style="font-family:宋体;font-size:14px;">  Ios13<span style="font-family:宋体;">增加了判断对象是否属于</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">的安全检查，这将导致以前通过伪造内核对象的漏洞利用手段变得困难了很多，比如</span><span style="font-family:Calibri;">ipc_port</span><span style="font-family:宋体;">，伪造的对象通常来自于用户空间，那么在引用这个对象时，</span><span style="font-family:Calibri;">xnu</span><span style="font-family:宋体;">引入了</span><span style="font-family:Calibri;">zone_require</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">zone_id_require</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">zone_owns</span><span style="font-family:宋体;">三个函数来做对象合法性检查。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">osfmk/kern/zalloc.c：</span></code><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">void</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">zone_require</span><span class="code-snippet__params">(<span class="code-snippet__keyword">zone_t</span> zone, <span class="code-snippet__keyword">void</span> *addr)</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (__probable(from_general_submap(addr, zone_elem_size(zone)) &amp;&amp;[<span class="code-snippet__number">1</span>]</span></code><code><span class="code-snippet_outer">            (zone_has_index(zone, zone_native_meta_from_addr(addr)-&gt;zm_index)))) {  [<span class="code-snippet__number">2</span>]</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">return</span>;</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> CONFIG_GZALLOC</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (__probable(gzalloc_enabled())) {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">return</span>;</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code><code><span class="code-snippet_outer">        zone_require_panic(zone, addr);[<span class="code-snippet__number">3</span>]</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:Calibri;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">[1]<span style="font-family:宋体;">处的</span></span><span style="font-family:Calibri;font-size:14px;">from_general_submap</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">判断对象的地址是否在整个大的有效范围内。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">define</span> from_general_submap(addr, size) \</span></span></code><code><span class="code-snippet_outer">        zone_range_contains(&amp;zone_info.zi_general_range, (vm_offset_t)(addr), size)</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">define</span> zone_range_load(r, rmin, rmax) \</span></span></code><code><span class="code-snippet_outer">        ({ rmin = (r)-&gt;min_address; rmax = (r)-&gt;max_address; })</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__function">header_always_inline <span class="code-snippet__keyword">bool</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">zone_range_contains</span><span class="code-snippet__params">(<span class="code-snippet__keyword">const</span> struct zone_map_range *r, <span class="code-snippet__keyword">vm_offset_t</span> addr, <span class="code-snippet__keyword">vm_offset_t</span> size)</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">vm_offset_t</span> rmin, rmax;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        zone_range_load(r, rmin, rmax);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> (addr &gt;= rmin) &amp; (addr + size &gt;= rmin) &amp; (addr + size &lt;= rmax);</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:Calibri;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">[2] </span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">处的</span></span><span style="font-family:Calibri;font-size:14px;">zone_has_index</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">才是判断对象是否属于某个特定的</span>zone<span style="font-family:宋体;">。通过</span></span><span style="font-family:Calibri;font-size:14px;">zone_native_meta_from_addr</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">函数将对象地址转为对应的</span>meta<span style="font-family:宋体;">数据结构，</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">zm_index</span><span style="font-family:宋体;">指示的是</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">对应的</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">在</span><span style="font-family:Calibri;">zone_array</span><span style="font-family:宋体;">数组里的索引，这样通过索引加上</span><span style="font-family:Calibri;">zone_array</span><span style="font-family:宋体;">数组地址就能判断是否指向了正确的</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">地址。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">inline</span> <span class="code-snippet__keyword">bool</span></span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">zone_has_index</span><span class="code-snippet__params">(<span class="code-snippet__keyword">zone_t</span> z, <span class="code-snippet__keyword">zone_id_t</span> zid)</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> zone_array + zid == z;</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">__<span class="code-snippet__function">abortlike</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">zone_require_panic</span><span class="code-snippet__params">(<span class="code-snippet__keyword">zone_t</span> zone, <span class="code-snippet__keyword">void</span> *addr)</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">uint32_t</span> zindex;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">zone_t</span> other;</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (!from_zone_map(addr, zone_elem_size(zone))) {</span></code><code><span class="code-snippet_outer">                panic(<span class="code-snippet__string">&#34;zone_require failed: address not in a zone (addr: %p)&#34;</span>, addr);</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        zindex = zone_native_meta_from_addr(addr)-&gt;zm_index;</span></code><code><span class="code-snippet_outer">        other = &amp;zone_array[zindex];</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (zindex &gt;= os_atomic_load(&amp;num_zones, relaxed) || !other-&gt;z_self) {</span></code><code><span class="code-snippet_outer">                panic(<span class="code-snippet__string">&#34;zone_require failed: invalid zone index %d &#34;</span></span></code><code><span class="code-snippet_outer">                    <span class="code-snippet__string">&#34;(addr: %p, expected: %s%s)&#34;</span>, zindex,</span></code><code><span class="code-snippet_outer">                    addr, zone_heap_name(zone), zone-&gt;z_name);</span></code><code><span class="code-snippet_outer">        } <span class="code-snippet__keyword">else</span> {</span></code><code><span class="code-snippet_outer">                panic(<span class="code-snippet__string">&#34;zone_require failed: address in unexpected zone id %d (%s%s) &#34;</span></span></code><code><span class="code-snippet_outer">                    <span class="code-snippet__string">&#34;(addr: %p, expected: %s%s)&#34;</span>,</span></code><code><span class="code-snippet_outer">                    zindex, zone_heap_name(other), other-&gt;z_name,</span></code><code><span class="code-snippet_outer">                    addr, zone_heap_name(zone), zone-&gt;z_name);</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:Calibri;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">当比对失败时，</span>[3]<span style="font-family:宋体;">处调用了</span><span style="font-family:Calibri;">zone_require_panic</span><span style="font-family:宋体;">来试图分析是哪种情况造成的并</span><span style="font-family:Calibri;">panic</span><span style="font-family:宋体;">系统。</span></span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;">zone_require</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">是</span>zalloc<span style="font-family:宋体;">内存分配器提供的</span><span style="font-family:Calibri;">kpi</span><span style="font-family:宋体;">接口， 当其他内核子系统需要判断某个</span><span style="font-family:Calibri;">object</span><span style="font-family:宋体;">是否合法时要主动调用，因为如果在内存分配器的</span><span style="font-family:Calibri;">alloc</span><span style="font-family:宋体;">或</span><span style="font-family:Calibri;">free</span><span style="font-family:宋体;">路径里在去判断对象合法性时为时已晚，漏洞攻击已经完成了。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">Ios13<span style="font-family:宋体;">也是类似的逻辑：</span></span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.45861297539149887" data-s="300,640" style="" data-type="png" data-w="894" src="https://wechat2rss.xlab.app/img-proxy/?k=b8477ee5&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F4iaJia7Cvd3PCandLM8NNGw2yojdWzPgy4ncbibgehk5sThE4nBa15epU7fOdUEvToWhoUqQsYSaVBDEJLOvExQSA%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><br/></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.49443757725587145" data-s="300,640" style="" data-type="png" data-w="809" src="https://wechat2rss.xlab.app/img-proxy/?k=65abe22c&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F4iaJia7Cvd3PCandLM8NNGw2yojdWzPgy48RicSsica6nicCHJicF9BRn0bh51OFM0KQsTwmVjRSsUqhfR8sVh66mdFw%2F640%3Fwx_fmt%3Dpng"/><span style="font-family: Calibri;font-size: 14px;text-align: justify;"> </span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">同时还可以发现，</span> <span style="font-family:宋体;">最新的</span>xnu<span style="font-family:宋体;">内存分配器对对象、</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">的合法性做了极其严格的检查，这些优秀的漏洞缓解方法需要移植到</span><span style="font-family:Calibri;">linux</span><span style="font-family:宋体;">中去。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">static</span> struct zone_page_metadata *</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">zone_allocated_element_resolve</span><span class="code-snippet__params">(<span class="code-snippet__keyword">zone_t</span> zone, <span class="code-snippet__keyword">vm_offset_t</span> addr,</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">vm_offset_t</span> *pagep, <span class="code-snippet__keyword">zone_addr_kind_t</span> *kindp)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">zone_page_metadata</span> *<span class="code-snippet__title">meta</span>;</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">zone_addr_kind_t</span> kind;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">vm_offset_t</span> page;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">vm_offset_t</span> esize = zone_elem_size(zone); </span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        kind = zone_addr_kind(addr, esize);</span></code><code><span class="code-snippet_outer">        page = trunc_page(addr);</span></code><code><span class="code-snippet_outer">        meta = zone_meta_from_addr(addr, kind); </span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (kind == ZONE_ADDR_NATIVE) {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> (meta-&gt;zm_secondary_page) {</span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">if</span> (meta-&gt;zm_percpu) {</span></code><code><span class="code-snippet_outer">                                zone_invalid_element_addr_panic(zone, addr);</span></code><code><span class="code-snippet_outer">                        }</span></code><code><span class="code-snippet_outer">                        page -= ptoa(meta-&gt;zm_page_count);</span></code><code><span class="code-snippet_outer">                        meta -= meta-&gt;zm_page_count;</span></code><code><span class="code-snippet_outer">                }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        } <span class="code-snippet__keyword">else</span> <span class="code-snippet__keyword">if</span> (!zone-&gt;allows_foreign) {</span></code><code><span class="code-snippet_outer">                zone_page_metadata_foreign_confusion_panic(zone, addr);</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> __LP64__</span></span></code><code><span class="code-snippet_outer">        } <span class="code-snippet__keyword">else</span> <span class="code-snippet__keyword">if</span> (!from_foreign_range(addr, esize)) {</span></code><code><span class="code-snippet_outer">                zone_invalid_foreign_addr_panic(zone, addr);</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">else</span></span></span></code><code><span class="code-snippet_outer">        } <span class="code-snippet__keyword">else</span> <span class="code-snippet__keyword">if</span> (!pmap_kernel_va(addr)) {</span></code><code><span class="code-snippet_outer">                zone_invalid_element_addr_panic(zone, addr);</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (!zone_allocated_element_offset_is_valid(zone, addr, page, kind)) {</span></code><code><span class="code-snippet_outer">                zone_invalid_element_addr_panic(zone, addr);</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (!zone_has_index(zone, meta-&gt;zm_index)) {</span></code><code><span class="code-snippet_outer">                zone_page_metadata_index_confusion_panic(zone, addr, meta);</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (kindp) {</span></code><code><span class="code-snippet_outer">                *kindp = kind;</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (pagep) {</span></code><code><span class="code-snippet_outer">                *pagep = page;</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> meta;</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_metadata_corruption(<span class="code-snippet__keyword">zone_t</span> zone, struct zone_page_metadata *meta,</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">const</span> <span class="code-snippet__keyword">char</span> *kind)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        panic(<span class="code-snippet__string">&#34;zone metadata corruption: %s (meta %p, zone %s%s)&#34;</span>,</span></code><code><span class="code-snippet_outer">            kind, meta, zone_heap_name(zone), zone-&gt;z_name);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_invalid_element_addr_panic(<span class="code-snippet__keyword">zone_t</span> zone, <span class="code-snippet__keyword">vm_offset_t</span> addr)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        panic(<span class="code-snippet__string">&#34;zone element pointer validation failed (addr: %p, zone %s%s)&#34;</span>,</span></code><code><span class="code-snippet_outer">            (<span class="code-snippet__keyword">void</span> *)addr, zone_heap_name(zone), zone-&gt;z_name);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_page_metadata_index_confusion_panic(<span class="code-snippet__keyword">zone_t</span> zone, <span class="code-snippet__keyword">vm_offset_t</span> addr,</span></code><code><span class="code-snippet_outer">    struct zone_page_metadata *meta)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        panic(<span class="code-snippet__string">&#34;%p not in the expected zone %s%s (%d != %d)&#34;</span>,</span></code><code><span class="code-snippet_outer">            (<span class="code-snippet__keyword">void</span> *)addr, zone_heap_name(zone), zone-&gt;z_name,</span></code><code><span class="code-snippet_outer">            meta-&gt;zm_index, zone_index(zone));</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_page_metadata_native_queue_corruption(<span class="code-snippet__keyword">zone_t</span> zone, <span class="code-snippet__keyword">zone_pva_t</span> *<span class="code-snippet__built_in">queue</span>)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        panic(<span class="code-snippet__string">&#34;foreign metadata index %d enqueued in native head %p from zone %s%s&#34;</span>,</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__built_in">queue</span>-&gt;packed_address, <span class="code-snippet__built_in">queue</span>, zone_heap_name(zone),</span></code><code><span class="code-snippet_outer">            zone-&gt;z_name);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_page_metadata_list_corruption(<span class="code-snippet__keyword">zone_t</span> zone, struct zone_page_metadata *meta)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        panic(<span class="code-snippet__string">&#34;metadata list corruption through element %p detected in zone %s%s&#34;</span>,</span></code><code><span class="code-snippet_outer">            meta, zone_heap_name(zone), zone-&gt;z_name);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_page_metadata_foreign_queue_corruption(<span class="code-snippet__keyword">zone_t</span> zone, <span class="code-snippet__keyword">zone_pva_t</span> *<span class="code-snippet__built_in">queue</span>)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        panic(<span class="code-snippet__string">&#34;native metadata index %d enqueued in foreign head %p from zone %s%s&#34;</span>,</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__built_in">queue</span>-&gt;packed_address, <span class="code-snippet__built_in">queue</span>, zone_heap_name(zone), zone-&gt;z_name);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_page_metadata_foreign_confusion_panic(<span class="code-snippet__keyword">zone_t</span> zone, <span class="code-snippet__keyword">vm_offset_t</span> addr)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        panic(<span class="code-snippet__string">&#34;manipulating foreign address %p in a native-only zone %s%s&#34;</span>,</span></code><code><span class="code-snippet_outer">            (<span class="code-snippet__keyword">void</span> *)addr, zone_heap_name(zone), zone-&gt;z_name);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_invalid_foreign_addr_panic(<span class="code-snippet__keyword">zone_t</span> zone, <span class="code-snippet__keyword">vm_offset_t</span> addr)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        panic(<span class="code-snippet__string">&#34;addr %p being freed to foreign zone %s%s not from foreign range&#34;</span>,</span></code><code><span class="code-snippet_outer">            (<span class="code-snippet__keyword">void</span> *)addr, zone_heap_name(zone), zone-&gt;z_name);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">zone_page_meta_accounting_panic(<span class="code-snippet__keyword">zone_t</span> zone, struct zone_page_metadata *meta,</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">const</span> <span class="code-snippet__keyword">char</span> *kind)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        panic(<span class="code-snippet__string">&#34;accounting mismatch (%s) for zone %s%s, meta %p&#34;</span>, kind,</span></code><code><span class="code-snippet_outer">            zone_heap_name(zone), zone-&gt;z_name, meta);</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:Calibri;font-size:14px;"></span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><br/></p>



<p><a href="2247483736">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=393c4b54&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg4NjU1NDU4MA%3D%3D%26mid%3D2247483736%26idx%3D1%26sn%3Dabe13c27f4187bfcc199288c59e7c17e%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Tue, 23 Feb 2021 11:25:00 +0800</pubDate>
    </item>
    <item>
      <title>IOS内核堆风水布局解读</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg4NjU1NDU4MA==&amp;mid=2247483730&amp;idx=1&amp;sn=47d8351a5e396e75f57a2fb1b3263fcd</link>
      <description>这篇文章主要是讨论ios内核堆的分配特性，辟谣下：zalloc内存分配器并没有在释放内存时将object随机插入freelist链表中。</description>
      <content:encoded><![CDATA[<p>
原创 <span>wzt</span> <span>2021-02-22 18:17</span> <span style="display: inline-block;"></span>
</p>

<p>这篇文章主要是讨论ios内核堆的分配特性，辟谣下：zalloc内存分配器并没有在释放内存时将object随机插入freelist链表中。</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=761d609f&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F4iaJia7Cvd3PBCAGctsw9vkaKmJxhRTamK1Yy0gOBcsm0yQ24EhtPmYouZrvXqBHZrUl30B6aibtJibcdHWogCGaQg%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">这篇文章主要是讨论</span>ios<span style="font-family:宋体;">内核堆的分配特性，辟谣下：</span><span style="font-family:Calibri;">zalloc</span><span style="font-family:宋体;">内存分配器并没有在释放内存时将</span><span style="font-family:Calibri;">object</span><span style="font-family:宋体;">随机的插入到</span><span style="font-family:Calibri;">freelist</span><span style="font-family:宋体;">链表里。</span><span style="font-family:Calibri;">xnu</span><span style="font-family:宋体;">内核没有单独设计这个特性，这个只是</span><span style="font-family:Calibri;">zalloc</span><span style="font-family:宋体;">架构特性导致的，无意中让风水的布局变困难了些。笔者分析过</span><span style="font-family:Calibri;">windows</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">linux</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">bsd</span><span style="font-family:宋体;">这些</span><span style="font-family:Calibri;">os</span><span style="font-family:宋体;">的内存分配器都没有发现释放随机化的安全特性， 因为只有保持内存分配器</span><span style="font-family:Calibri;">fifo</span><span style="font-family:宋体;">的特性，才能加快分配速度，任何一个内存分配器的设计值都不会违背这个原则。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">下面将仔细探讨下</span>xnu<span style="font-family:宋体;">的</span><span style="font-family:Calibri;">zalloc</span><span style="font-family:宋体;">特性， 在</span><span style="font-family:Calibri;">xnu-4903</span><span style="font-family:宋体;">内核中，一个</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">有四条队列：</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">zone</span> {</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> {</span></span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">queue_head_t</span>                    any_free_foreign;       </span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">queue_head_t</span>                    all_free;</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">queue_head_t</span>                    intermediate;</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">queue_head_t</span>                    all_used;</span></code><code><span class="code-snippet_outer">        } pages;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:宋体;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">半满外围队列</span></span><span style="font-family:Calibri;font-size:14px;">any_free_foreign</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">，全空队列</span></span><span style="font-family:Calibri;font-size:14px;">all_free</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">，半满半空队列</span></span><span style="font-family:Calibri;font-size:14px;">intermediate</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">，全满队列</span></span><span style="font-family:Calibri;font-size:14px;">all_used</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">。我们先讨论下</span>zcache<span style="font-family:宋体;">关闭的情况下，在</span><span style="font-family:Calibri;">try_alloc_from_zone</span><span style="font-family:宋体;">分配一个</span><span style="font-family:Calibri;">object</span><span style="font-family:宋体;">内存时有如下调用：</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="php"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">static</span> inline vm_offset_t</span></code><code><span class="code-snippet_outer">try_alloc_from_zone(zone_t zone,</span></code><code><span class="code-snippet_outer">                        vm_tag_t tag __unused,</span></code><code><span class="code-snippet_outer">                    boolean_t* check_poison)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (zone-&gt;allows_foreign &amp;&amp; !queue_empty(&amp;zone-&gt;pages.any_free_foreign))</span></code><code><span class="code-snippet_outer">                page_meta = (struct zone_page_metadata *)queue_first(&amp;zone-&gt;pages.any_free_foreign);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">else</span> <span class="code-snippet__keyword">if</span> (!queue_empty(&amp;zone-&gt;pages.intermediate))</span></code><code><span class="code-snippet_outer">                page_meta = (struct zone_page_metadata *)queue_first(&amp;zone-&gt;pages.intermediate);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">else</span> <span class="code-snippet__keyword">if</span> (!queue_empty(&amp;zone-&gt;pages.all_free)) {</span></code><code><span class="code-snippet_outer">                page_meta = (struct zone_page_metadata *)queue_first(&amp;zone-&gt;pages.all_free);</span></code><code><span class="code-snippet_outer">                assert(zone-&gt;count_all_free_pages &gt;= page_meta-&gt;page_count);</span></code><code><span class="code-snippet_outer">                zone-&gt;count_all_free_pages -= page_meta-&gt;page_count;</span></code><code><span class="code-snippet_outer">        } <span class="code-snippet__keyword">else</span> {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">return</span> <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:宋体;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">如果</span>zone<span style="font-family:宋体;">开启了</span></span><span style="font-family:Calibri;font-size:14px;">allows_foreign</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">并且</span></span><span style="font-family:Calibri;font-size:14px;">any_free_foreign</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">队列不为空，则从此队列取出队列头节点</span>page_meta<span style="font-family:宋体;">，从这个</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">里分配内存，如果条件不符合，那么依次从</span></span><span style="font-family:Calibri;font-size:14px;">intermediate</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">半满半空队列里取</span>meta<span style="font-family:宋体;">，如果还是不符合，那么在从</span></span><span style="font-family:Calibri;font-size:14px;">all_free</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">队列里选</span>meta<span style="font-family:宋体;">。一个</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">是否支持</span><span style="font-family:Calibri;">allows_foreign</span><span style="font-family:宋体;">，是通过调用</span><span style="font-family:Calibri;">zone_change</span><span style="font-family:宋体;">函数设置的，笔者搜索了整个</span><span style="font-family:Calibri;">xnu</span><span style="font-family:宋体;">源码文件，发现只有</span><span style="font-family:Calibri;">vm</span><span style="font-family:宋体;">自身的几个</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">才会使用此标志，因此</span><span style="font-family:Calibri;">jailbreaker</span><span style="font-family:宋体;">关心的</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">，比如</span><span style="font-family:Calibri;">ipc_port</span><span style="font-family:宋体;">都没有使用，这将简化</span><span style="font-family:Calibri;">exploit</span><span style="font-family:宋体;">程序对堆风水布局的处理。当选取完</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">后，通过</span><span style="font-family:Calibri;">page_metadata_get_freelist</span><span style="font-family:宋体;">获取了</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">上的第一个空闲节点，然后要通过</span><span style="font-family:Calibri;">page_metadata_set_freelist</span><span style="font-family:宋体;">重新设置新的空闲节点，满足下次的分配需求。最后还要重新布局下当前</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">所在的队列。</span></span><span style="font-family:Calibri;font-size:14px;">try_alloc_from_zone</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">函数最后有如下代码：</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="php"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">static</span> inline vm_offset_t</span></code><code><span class="code-snippet_outer">try_alloc_from_zone(zone_t zone,</span></code><code><span class="code-snippet_outer">                        vm_tag_t tag __unused,</span></code><code><span class="code-snippet_outer">                    boolean_t* check_poison)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (page_meta-&gt;free_count == <span class="code-snippet__number">0</span>) {[<span class="code-snippet__number">1</span>]</span></code><code><span class="code-snippet_outer">                re_queue_tail(&amp;zone-&gt;pages.all_used, &amp;(page_meta-&gt;pages));</span></code><code><span class="code-snippet_outer">        } <span class="code-snippet__keyword">else</span> {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> (!zone-&gt;allows_foreign || from_zone_map(element, zone-&gt;elem_size)) { </span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">if</span> (get_metadata_alloc_count(page_meta) == page_meta-&gt;free_count + <span class="code-snippet__number">1</span>) {[<span class="code-snippet__number">2</span>]</span></code><code><span class="code-snippet_outer">                                re_queue_tail(&amp;zone-&gt;pages.intermediate, &amp;(page_meta-&gt;pages));</span></code><code><span class="code-snippet_outer">                        }</span></code><code><span class="code-snippet_outer">                }</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:宋体;font-size:14px;"></span></p><p style="margin-left:14px;text-indent:0;"><span style="font-family:宋体;font-size:14px;">[1] </span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">当这个</span>meta<span style="font-family:宋体;">在分配完一个空闲节点后， 如果</span></span><span style="font-family:Calibri;font-size:14px;">free_count</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">为</span>0<span style="font-family:宋体;">，说明</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">已经没有空闲的节点了，那么就要将这个</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">节点转移到</span></span><span style="font-family:Calibri;font-size:14px;">all_used</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">队列。</span> [2]<span style="font-family:宋体;">处的判断</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">是否为一个全空的队列，当它分配一个空闲节点后，就变成半满的状态了，因此需要转移到半满队列</span></span><span style="font-family:Calibri;font-size:14px;">intermediate</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">。转移队列的操作函数为</span></span><span style="font-family:Calibri;font-size:14px;">re_queue_tail</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">：</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="php"><code><span class="code-snippet_outer">re_queue_tail(queue_t que, queue_entry_t elt)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        queue_entry_t   n_elt, p_elt;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment">/* remqueue */</span></span></code><code><span class="code-snippet_outer">        n_elt = elt-&gt;next;[<span class="code-snippet__number">1</span>]</span></code><code><span class="code-snippet_outer">        p_elt = elt-&gt;prev;</span></code><code><span class="code-snippet_outer">        n_elt-&gt;prev = p_elt;</span></code><code><span class="code-snippet_outer">        p_elt-&gt;next = n_elt;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment">/* enqueue_tail */</span></span></code><code><span class="code-snippet_outer">        p_elt = que-&gt;prev;[<span class="code-snippet__number">2</span>]</span></code><code><span class="code-snippet_outer">        elt-&gt;next = que;</span></code><code><span class="code-snippet_outer">        elt-&gt;prev = p_elt;</span></code><code><span class="code-snippet_outer">        p_elt-&gt;next = elt;</span></code><code><span class="code-snippet_outer">        que-&gt;prev = elt;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">[1] </span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">处先从当前队列删除自身，然后</span>[2]<span style="font-family:宋体;">处将其挂载到新队列的末尾。注意这个操作是挂接到队尾，那么当出现一些极端状况发生队列转移时，如果新的队列节点不为空，就要等待前面所有的节点都被用完或发生队列迁移时，这个节点才会被调用到，这就发生了不是</span><span style="font-family:Calibri;">fifo</span><span style="font-family:宋体;">的情况，对于</span><span style="font-family:Calibri;">jailbreaker</span><span style="font-family:宋体;">的风水布局就会产生影响，这个状态被一些人误以为是</span><span style="font-family:Calibri;">ios</span><span style="font-family:宋体;">提供了新的安全特性，在释放时</span></span><span style="font-family:Calibri;font-size:14px;">”</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">随机</span></span><span style="font-family:Calibri;font-size:14px;">”</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">的将</span>object<span style="font-family:宋体;">插入到</span><span style="font-family:Calibri;">freelist</span><span style="font-family:宋体;">链表中。</span></span><br/></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">然后有个很有意思的事情发生了，</span> <span style="font-family:宋体;">在最新的</span>xnu-7195.81.3<span style="font-family:宋体;">内核中，笔者发现</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">队列转移的操作不是挂接到队列末尾，而是队列头部，将队列变成</span><span style="font-family:Calibri;">fifo</span><span style="font-family:宋体;">的链表了！</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">__<span class="code-snippet__function">header_always_inline <span class="code-snippet__keyword">void</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">zone_meta_queue_push</span><span class="code-snippet__params">(<span class="code-snippet__keyword">zone_t</span> z, <span class="code-snippet__keyword">zone_pva_t</span> *headp,</span></span></code><code><span class="code-snippet_outer">    struct zone_page_metadata *meta, <span class="code-snippet__keyword">zone_addr_kind_t</span> kind)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">zone_pva_t</span> head = *headp;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">zone_pva_t</span> queue_pva = zone_queue_encode(headp);             [<span class="code-snippet__number">1</span>]</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">zone_page_metadata</span> *<span class="code-snippet__title">tmp</span>;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        meta-&gt;zm_page_next = head; [<span class="code-snippet__number">2</span>]</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (!zone_pva_is_null(head)) {</span></code><code><span class="code-snippet_outer">                tmp = zone_pva_to_meta(head, kind);</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> (!zone_pva_is_equal(tmp-&gt;zm_page_prev, queue_pva)) { [<span class="code-snippet__number">3</span>]</span></code><code><span class="code-snippet_outer">                        zone_page_metadata_list_corruption(z, meta);</span></code><code><span class="code-snippet_outer">                }</span></code><code><span class="code-snippet_outer">                tmp-&gt;zm_page_prev = zone_pva_from_meta(meta, kind);  [<span class="code-snippet__number">4</span>]</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">        meta-&gt;zm_page_prev = queue_pva;                           [<span class="code-snippet__number">5</span>]</span></code><code><span class="code-snippet_outer">        *headp = zone_pva_from_meta(meta, kind);                    [<span class="code-snippet__number">6</span>]</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:宋体;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">新内核的</span>struct zone_page_metadata<span style="font-family:宋体;">结构多了两个成员：</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">zone_page_metadata</span> {</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">zone_pva_t</span>      zm_page_next;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">zone_pva_t</span>      zm_page_prev;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:宋体;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">在</span>zone<span style="font-family:宋体;">中的队列头也使用</span><span style="font-family:Calibri;">zone_pva_t</span><span style="font-family:宋体;">重新定义：</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">typedef</span> <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">zone_packed_virtual_address</span> {</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">uint32_t</span> packed_address;</span></code><code><span class="code-snippet_outer">} <span class="code-snippet__keyword">zone_pva_t</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">zone</span> {</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">zone_pva_t</span>          pages_any_free_foreign;     </span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">zone_pva_t</span>          pages_all_used_foreign;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">zone_pva_t</span>          pages_all_free;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">zone_pva_t</span>          pages_intermediate;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">zone_pva_t</span>          pages_all_used;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">zone_pva_t</span>          pages_sequester;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:宋体;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">从四条队列变为了六条队列，每个队列头的地址是被编码起来保存的，通过</span>zone_pva_from_meta<span style="font-family:宋体;">函数将一个</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">进行转化编码为队列地址，其实就是</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">地址在</span><span style="font-family:Calibri;">meta base</span><span style="font-family:宋体;">中的偏移。每个</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">结构通过双向链链表起来，如果</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">是队列中的第一个节点，则它的</span><span style="font-family:Calibri;">zm_page_prev</span><span style="font-family:宋体;">指向的是一个</span></span><span style="font-family:Calibri;font-size:14px;">”</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">特殊地址</span></span><span style="font-family:Calibri;font-size:14px;">”</span><span style="font-family:宋体;font-size:14px;">, <span style="font-family:宋体;">这个地址通过</span><span style="font-family:Calibri;">zone_queue_encode</span><span style="font-family:宋体;">进行编码，主要原理是把当前队列的地址转为为在</span><span style="font-family:Calibri;">zone_array</span><span style="font-family:宋体;">中的索引进行保存。当以后队列节点不为空时，通过</span><span style="font-family:Calibri;">[3]</span><span style="font-family:宋体;">处的比较可以确定当前队列的头节点是否被破坏了。如果</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">不是队列中的第一个节点，则指向前一个带有正确编码的队列地址。</span><span style="font-family:Calibri;">[6]</span><span style="font-family:宋体;">处的操作将</span><span style="font-family:Calibri;">meta</span><span style="font-family:宋体;">节点挂载到了最队列的头部，所以这是一个</span><span style="font-family:Calibri;">fifo</span><span style="font-family:宋体;">的队列。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">在队列取节点时，也是从队列头取出，而不是队列末尾。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">__<span class="code-snippet__function">header_always_inline struct zone_page_metadata *</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">zone_meta_queue_pop</span><span class="code-snippet__params">(<span class="code-snippet__keyword">zone_t</span> z, <span class="code-snippet__keyword">zone_pva_t</span> *headp, <span class="code-snippet__keyword">zone_addr_kind_t</span> kind,</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">vm_offset_t</span> *page_addrp)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">zone_pva_t</span> head = *headp;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">zone_page_metadata</span> *<span class="code-snippet__title">meta</span> = <span class="code-snippet__title">zone_pva_to_meta</span>(<span class="code-snippet__title">head</span>, <span class="code-snippet__title">kind</span>);</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">vm_offset_t</span> page_addr = zone_pva_to_addr(head);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">zone_page_metadata</span> *<span class="code-snippet__title">tmp</span>;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (kind == ZONE_ADDR_NATIVE &amp;&amp; !from_native_meta_map(meta)) {</span></code><code><span class="code-snippet_outer">                zone_page_metadata_native_queue_corruption(z, headp);</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (kind == ZONE_ADDR_FOREIGN &amp;&amp; from_zone_map(meta, <span class="code-snippet__keyword">sizeof</span>(*meta))) {</span></code><code><span class="code-snippet_outer">                zone_page_metadata_foreign_queue_corruption(z, headp);</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (!zone_pva_is_null(meta-&gt;zm_page_next)) {</span></code><code><span class="code-snippet_outer">                tmp = zone_pva_to_meta(meta-&gt;zm_page_next, kind);</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> (!zone_pva_is_equal(tmp-&gt;zm_page_prev, head)) {</span></code><code><span class="code-snippet_outer">                        zone_page_metadata_list_corruption(z, meta);</span></code><code><span class="code-snippet_outer">                }</span></code><code><span class="code-snippet_outer">                tmp-&gt;zm_page_prev = meta-&gt;zm_page_prev;</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">        *headp = meta-&gt;zm_page_next;</span></code><code><span class="code-snippet_outer">        *page_addrp = page_addr;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> meta;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:宋体;font-size:14px;"></span></p><p style="text-indent: 28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">那么在新内核里，对于布局堆的风水其实是更加便利了！</span></span></p>



<p><a href="2247483730">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=927234c1&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg4NjU1NDU4MA%3D%3D%26mid%3D2247483730%26idx%3D1%26sn%3D47d8351a5e396e75f57a2fb1b3263fcd%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Mon, 22 Feb 2021 18:17:00 +0800</pubDate>
    </item>
    <item>
      <title>XNU进程地址随机化解读</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg4NjU1NDU4MA==&amp;mid=2247483725&amp;idx=1&amp;sn=b37b02c59924474ccc97ac79b7a6a274</link>
      <description>XNU进程地址随机化解读</description>
      <content:encoded><![CDATA[<p>
原创 <span>wzt</span> <span>2021-02-01 12:56</span> <span style="display: inline-block;"></span>
</p>

<p>XNU进程地址随机化解读</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=34bed0d4&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F4iaJia7Cvd3PCXeuibZgo58aSMAzibiawupxmCg1N8yPQk2IIibeeugcOyckGooatJf5XctPMsb7oeCm2icx4VxJE3Ricw%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<h2 style="margin-left:0;text-indent:0;"><span style="font-family:Arial;font-weight:bold;font-size:21px;">1.1 </span><strong><span style="font-family: 黑体;font-size: 21px;"><span style="font-family:黑体;">进程栈、代码段地址随机化</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">这里指的是进程的用户态栈，记住一个进程实际拥有两个栈，</span> <span style="font-family:宋体;">一个用于跑用户态的代码，一个用于请求系统调用时在内核中使用的栈空间。在前面分析</span>BSD<span style="font-family:宋体;">进程随机化时，我们注意到</span><span style="font-family:Calibri;">bsd</span><span style="font-family:宋体;">并没有给进程的用户态栈加入地址随机化， </span><span style="font-family:Calibri;">XNU</span><span style="font-family:宋体;">虽然继承了</span><span style="font-family:Calibri;">BSD</span><span style="font-family:宋体;">进程模型，但作为一个商业操作系统没有栈的随机化功能显然是说不过去的， 自然给其进程加入了随机化功能。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="properties"><code><span class="code-snippet_outer"><span class="code-snippet__attr">bsd/kern/mach_loader.c</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">load_return_t</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">load_machfile(</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">        struct image_params     *imgp,</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">        struct mach_header      *header,</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">        thread_t                thread,</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">        vm_map_t                *mapp,</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">        load_result_t           *result</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">)</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">{</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">        if (!(imgp-&gt;ip_flags &amp; IMGPF_DISABLE_ASLR)) {</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">                vm_map_get_max_aslr_slide_section(map, &amp;aslr_section_offset, &amp;aslr_section_size); [1]</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">                aslr_section_offset </span>=<span class="code-snippet__string"> (random() % aslr_section_offset) * aslr_section_size;[2]</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">                aslr_page_offset </span>=<span class="code-snippet__string"> random();[3]</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">                aslr_page_offset %</span>=<span class="code-snippet__string"> vm_map_get_max_aslr_slide_pages(map);</span></span></code><code><span class="code-snippet_outer">                <span class="code-snippet__attr">aslr_page_offset</span> <span class="code-snippet__string">&lt;&lt;= vm_map_page_shift(map);</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">                dyld_aslr_page_offset </span>=<span class="code-snippet__string"> random();[4]</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">                dyld_aslr_page_offset %</span>=<span class="code-snippet__string"> vm_map_get_max_loader_aslr_slide_pages(map);</span></span></code><code><span class="code-snippet_outer">                <span class="code-snippet__attr">dyld_aslr_page_offset</span> <span class="code-snippet__string">&lt;&lt;= vm_map_page_shift(map);</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">                aslr_page_offset +</span>=<span class="code-snippet__string"> aslr_section_offset;[5]</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">        }</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">}</span></span></code></pre></section><p><span style="font-family:宋体;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">除了</span>mmap<span style="font-family:宋体;">，进程的栈、代码段以及共享库的地址随机化都是在内核从磁盘加载二进制文件时完成的。</span><span style="font-family:Calibri;">[1]</span><span style="font-family:宋体;">处</span><span style="font-family:Calibri;">vm_map_get_max_aslr_slide_section</span><span style="font-family:宋体;">函数选取了随机化的范围，</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">void</span></span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">vm_map_get_max_aslr_slide_section</span><span class="code-snippet__params">(</span></span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">vm_map_t</span>                <span class="code-snippet__built_in">map</span> __unused,</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">int64_t</span>                 *max_sections,</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">int64_t</span>                 *section_size)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> defined(__arm64__)</span></span></code><code><span class="code-snippet_outer">        *max_sections = <span class="code-snippet__number">3</span>;</span></code><code><span class="code-snippet_outer">        *section_size = ARM_TT_TWIG_SIZE;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">else</span></span></span></code><code><span class="code-snippet_outer">        *max_sections = <span class="code-snippet__number">1</span>;</span></code><code><span class="code-snippet_outer">        *section_size = <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:Calibri;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;">aslr_section_offset</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">表示的随机几个页面大小，</span></span><span style="font-family:Calibri;font-size:14px;">aslr_section_size</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">表示每个页面的大小，对于不同的</span>CPU<span style="font-family:宋体;">体系架构拥有不同的值，在</span><span style="font-family:Calibri;">arm64</span><span style="font-family:宋体;">下 </span></span><span style="font-family:Calibri;font-size:14px;">aslr_section_offset</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">设定为</span>3<span style="font-family:宋体;">，页面大小设置为</span></span><span style="font-family:Calibri;font-size:14px;">0x0000000000200000ULL</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">，其他架构下</span></span><span style="font-family:Calibri;font-size:14px;">aslr_section_offset</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">设为</span>1<span style="font-family:宋体;">， 页面大小设为</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">。</span><span style="font-family:Calibri;">[2]</span><span style="font-family:宋体;">处使用</span><span style="font-family:Calibri;">random</span><span style="font-family:宋体;">函数生成了一个临时随机范围</span></span><span style="font-family:Calibri;font-size:14px;">aslr_section_offset</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">。</span>[3]<span style="font-family:宋体;">处的</span></span><span style="font-family:Calibri;font-size:14px;">aslr_page_offset</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">表示栈和代码段使用的随机范围，没错</span>xnu<span style="font-family:宋体;">的栈和</span><span style="font-family:Calibri;">text</span><span style="font-family:宋体;">代码使用的是同一个随机范围， 而</span><span style="font-family:Calibri;">linux</span><span style="font-family:宋体;">使用的都是不同的。</span><span style="font-family:Calibri;">Xnu</span><span style="font-family:宋体;">这样做提升了一点性能，但安全性也会降低一些。</span><span style="font-family:Calibri;">vm_map_get_max_aslr_slide_pages</span><span style="font-family:宋体;">函数选取了要随机多少个页面大小，在</span><span style="font-family:Calibri;">arm64</span><span style="font-family:宋体;">下为</span><span style="font-family:Calibri;">1&lt;&lt;12</span><span style="font-family:宋体;">，在其他架构的</span><span style="font-family:Calibri;">64</span><span style="font-family:宋体;">位下为</span><span style="font-family:Calibri;">1&lt;&lt;16</span><span style="font-family:宋体;">，</span><span style="font-family:Calibri;">32</span><span style="font-family:宋体;">位为</span><span style="font-family:Calibri;">1&lt;&lt;8</span><span style="font-family:宋体;">。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">uint64_t</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">vm_map_get_max_aslr_slide_pages(<span class="code-snippet__keyword">vm_map_t</span> <span class="code-snippet__built_in">map</span>)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> defined(__arm64__)</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment">/* Limit arm64 slide to 16MB to conserve contiguous VA space in the more</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">         * limited embedded address space; this is also meant to minimize pmap</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">         * memory usage on 16KB page systems.</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">         */</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> (<span class="code-snippet__number">1</span> &lt;&lt; (<span class="code-snippet__number">24</span> - VM_MAP_PAGE_SHIFT(<span class="code-snippet__built_in">map</span>)));</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">else</span></span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> (<span class="code-snippet__number">1</span> &lt;&lt; (vm_map_is_64bit(<span class="code-snippet__built_in">map</span>) ? <span class="code-snippet__number">16</span> : <span class="code-snippet__number">8</span>));</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:Calibri;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">最后</span></span><span style="font-family:Calibri;font-size:14px;">aslr_page_offset</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">在左移</span>12<span style="font-family:宋体;">位，那么在</span><span style="font-family:Calibri;">arm64</span><span style="font-family:宋体;">下其随机化的范围就为</span><span style="font-family:Calibri;">0-16MB</span><span style="font-family:宋体;">，其实随机化的范围并不大，而且都是以页面对齐的，所以只需暴力才解</span><span style="font-family:Calibri;">4096</span><span style="font-family:宋体;">次就能猜到</span><span style="font-family:Calibri;">offset</span><span style="font-family:宋体;">。即使加上</span><span style="font-family:Calibri;">[5]</span><span style="font-family:宋体;">处的临时</span><span style="font-family:Calibri;">offset</span><span style="font-family:宋体;">，也提高不了多少安全等级。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">[4] </span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">处的</span></span><span style="font-family:Calibri;font-size:14px;">vm_map_get_max_loader_aslr_slide_pages</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">计算的是共享库的地址随机化范围，与上述类似，最终随机范围为</span>0-4MB<span style="font-family:宋体;">。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">Win10<span style="font-family:宋体;">进程栈在</span><span style="font-family:Calibri;">64</span><span style="font-family:宋体;">位下可以做到上</span><span style="font-family:Calibri;">TB</span><span style="font-family:宋体;">的随机化范围， 笔者也给</span><span style="font-family:Calibri;">linux</span><span style="font-family:宋体;">扩展了栈的随机化范围，通过打入</span><span style="font-family:Calibri;">AKSP</span><span style="font-family:宋体;">补丁，栈的随机化也可以做到上</span><span style="font-family:Calibri;">TB</span><span style="font-family:宋体;">的范围。如此来看，</span><span style="font-family:Calibri;">XNU</span><span style="font-family:宋体;">进程的栈地址随机化未免有点小家子气了。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">对栈基地址的设置是在</span>load_unixthread<span style="font-family:宋体;">里设置的：</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">static</span></span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">load_return_t</span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">load_unixthread</span><span class="code-snippet__params">(</span></span></code><code><span class="code-snippet_outer">        struct thread_command   *tcp,</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">thread_t</span>                thread,</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">int64_t</span>                         slide,</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">load_result_t</span>           *result</span></code><code><span class="code-snippet_outer">)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        ret = load_threadstack(thread,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">uint32_t</span> *)(((<span class="code-snippet__keyword">vm_offset_t</span>)tcp) +</span></code><code><span class="code-snippet_outer">                                        <span class="code-snippet__keyword">sizeof</span>(struct thread_command)),</span></code><code><span class="code-snippet_outer">                                tcp-&gt;cmdsize - <span class="code-snippet__keyword">sizeof</span>(struct thread_command),</span></code><code><span class="code-snippet_outer">                                &amp;addr, &amp;customstack, result);</span></code><code><span class="code-snippet_outer">        result-&gt;user_stack = addr;</span></code><code><span class="code-snippet_outer">        result-&gt;user_stack -= slide;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:宋体;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;">load_threadstack</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">选取了栈基地址，然后减去</span>slide<span style="font-family:宋体;">。</span><span style="font-family:Calibri;">Slide</span><span style="font-family:宋体;">为上述的</span></span><span style="font-family:Calibri;font-size:14px;">aslr_page_offset</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">，但是它的使用还有个前提条件：</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="properties"><code><span class="code-snippet_outer"><span class="code-snippet__attr">static</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">load_return_t</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">parse_machfile(</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">        struct vnode            *vp,</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">        vm_map_t                map,</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">        thread_t                thread,</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">        struct mach_header      *header,</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">        off_t                   file_offset,</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">        off_t                   macho_size,</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">        int                     depth,</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">        int64_t                 aslr_offset,</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">        int64_t                 dyld_aslr_offset,</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">        load_result_t           *result,</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">        load_result_t           *binresult,</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">        struct image_params     *imgp</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">)</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">{</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__attr">int64_t</span>                 <span class="code-snippet__string">slide = 0;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">        if ((header-&gt;flags &amp; MH_PIE) || is_dyld) {</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">                slide </span>=<span class="code-snippet__string"> aslr_offset;</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">        }</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">}</span></span></code></pre></section><p><span style="font-family:宋体;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">Slide<span style="font-family:宋体;">初始化为</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">，只有当二进制为</span><span style="font-family:Calibri;">PIE</span><span style="font-family:宋体;">编译或者为动态连接器才会被设置为</span><span style="font-family:Calibri;">aslr_offset</span><span style="font-family:宋体;">，这样对于普通的二进制程序栈并没有地址随机化能力！</span></span></p><h2 style="margin-left:0;text-indent:0;"><span style="font-family:Arial;font-weight:bold;font-size:21px;">1.2 </span><strong><span style="font-family: 黑体;font-size: 21px;">mmap<span style="font-family:黑体;">地址随机化</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">XNU<span style="font-family:宋体;">提供了</span><span style="font-family:Calibri;">posix</span><span style="font-family:宋体;">标准的</span><span style="font-family:Calibri;">mmap</span><span style="font-family:宋体;">函数，对于匿名映射的内存地址随机化是在</span><span style="font-family:Calibri;">mach</span><span style="font-family:宋体;">层的</span><span style="font-family:Calibri;">vm_map_enter</span><span style="font-family:宋体;">函数来设置的。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">osfmk/vm/vm_map.<span class="code-snippet__function">c</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">kern_return_t</span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">vm_map_enter</span><span class="code-snippet__params">(</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">vm_map_t</span>                <span class="code-snippet__built_in">map</span>,</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">vm_map_offset_t</span>         *address,       <span class="code-snippet__comment">/* IN/OUT */</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">vm_map_size_t</span>           size,</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">vm_map_offset_t</span>         mask,</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">int</span>                     flags,</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">vm_map_kernel_flags_t</span>   vmk_flags,</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">vm_tag_t</span>                alias,</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">vm_object_t</span>             object,</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">vm_object_offset_t</span>      offset,</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">boolean_t</span>               needs_copy,</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">vm_prot_t</span>               cur_protection,</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">vm_prot_t</span>               max_protection,</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">vm_inherit_t</span>            inheritance)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">boolean_t</span>               random_address = ((flags &amp; VM_FLAGS_RANDOM_ADDR) != <span class="code-snippet__number">0</span>);[<span class="code-snippet__number">1</span>]</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (anywhere) {</span></code><code><span class="code-snippet_outer">                vm_map_lock(<span class="code-snippet__built_in">map</span>);</span></code><code><span class="code-snippet_outer">                map_locked = TRUE; </span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> (entry_for_jit) {[<span class="code-snippet__number">2</span>]</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> CONFIG_EMBEDDED</span></span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">if</span> (<span class="code-snippet__built_in">map</span>-&gt;jit_entry_exists) {</span></code><code><span class="code-snippet_outer">                                result = KERN_INVALID_ARGUMENT;</span></code><code><span class="code-snippet_outer">                                <span class="code-snippet__keyword">goto</span> BailOut;</span></code><code><span class="code-snippet_outer">                        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">                        random_address = TRUE;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code><code><span class="code-snippet_outer">                }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> (random_address) {</span></code><code><span class="code-snippet_outer">                        result = vm_map_random_address_for_size(<span class="code-snippet__built_in">map</span>, address, size); [<span class="code-snippet__number">3</span>]</span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">if</span> (result != KERN_SUCCESS) {</span></code><code><span class="code-snippet_outer">                                <span class="code-snippet__keyword">goto</span> BailOut;</span></code><code><span class="code-snippet_outer">                        }</span></code><code><span class="code-snippet_outer">                        start = *address;</span></code><code><span class="code-snippet_outer">                }</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:宋体;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">对于主动提供了</span></span><span style="font-family:Calibri;font-size:14px;">VM_FLAGS_RANDOM_ADDR</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">标志或者在</span></span><span style="font-family:Calibri;font-size:14px;">CONFIG_EMBEDDED</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">下开启了</span>jit code<span style="font-family:宋体;">条件下都会使用</span><span style="font-family:Calibri;">[3]</span><span style="font-family:宋体;">处的</span></span><span style="font-family:Calibri;font-size:14px;">vm_map_random_address_for_size</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">函数选取一块包含了随机化范围的起始地址。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">define</span> MAX_TRIES_TO_GET_RANDOM_ADDRESS 1000</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">kern_return_t</span></span></code><code><span class="code-snippet_outer">vm_map_random_address_for_size(</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">vm_map_t</span>        <span class="code-snippet__built_in">map</span>,</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">vm_map_offset_t</span> *address,</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">vm_map_size_t</span>   size)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">addr_space_size = vm_map_max(<span class="code-snippet__built_in">map</span>) - vm_map_min(<span class="code-snippet__built_in">map</span>);[<span class="code-snippet__number">1</span>]</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">while</span> (tries &lt; MAX_TRIES_TO_GET_RANDOM_ADDRESS) {</span></code><code><span class="code-snippet_outer">                random_addr = ((<span class="code-snippet__keyword">vm_map_offset_t</span>)random()) &lt;&lt; PAGE_SHIFT; [<span class="code-snippet__number">2</span>]</span></code><code><span class="code-snippet_outer">                random_addr = vm_map_trunc_page(</span></code><code><span class="code-snippet_outer">                        vm_map_min(<span class="code-snippet__built_in">map</span>) +(random_addr % addr_space_size),</span></code><code><span class="code-snippet_outer">                        VM_MAP_PAGE_MASK(<span class="code-snippet__built_in">map</span>));</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> (vm_map_lookup_entry(<span class="code-snippet__built_in">map</span>, random_addr, &amp;prev_entry) == FALSE) {</span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">if</span> (prev_entry == vm_map_to_entry(<span class="code-snippet__built_in">map</span>)) {</span></code><code><span class="code-snippet_outer">                                next_entry = vm_map_first_entry(<span class="code-snippet__built_in">map</span>);</span></code><code><span class="code-snippet_outer">                        } <span class="code-snippet__keyword">else</span> {</span></code><code><span class="code-snippet_outer">                                next_entry = prev_entry-&gt;vme_next;</span></code><code><span class="code-snippet_outer">                        }</span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">if</span> (next_entry == vm_map_to_entry(<span class="code-snippet__built_in">map</span>)) {</span></code><code><span class="code-snippet_outer">                                hole_end = vm_map_max(<span class="code-snippet__built_in">map</span>);</span></code><code><span class="code-snippet_outer">                        } <span class="code-snippet__keyword">else</span> {</span></code><code><span class="code-snippet_outer">                                hole_end = next_entry-&gt;vme_start;</span></code><code><span class="code-snippet_outer">                        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">                        vm_hole_size = hole_end - random_addr;</span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">if</span> (vm_hole_size &gt;= size) {</span></code><code><span class="code-snippet_outer">                                *address = random_addr;</span></code><code><span class="code-snippet_outer">                                <span class="code-snippet__keyword">break</span>;</span></code><code><span class="code-snippet_outer">                       }</span></code><code><span class="code-snippet_outer">                }</span></code><code><span class="code-snippet_outer">                tries++;</span></code><code><span class="code-snippet_outer">        } </span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (tries == MAX_TRIES_TO_GET_RANDOM_ADDRESS) {</span></code><code><span class="code-snippet_outer">                kr = KERN_NO_SPACE;</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> kr;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:Calibri;font-size:14px;"></span></p><p style="text-indent: 28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">这个函数比较奇葩，</span> <span style="font-family:宋体;">尝试循环</span>1000<span style="font-family:宋体;">次找到带有随机化范围的</span><span style="font-family:Calibri;">vm_map_entry</span><span style="font-family:宋体;">，</span><span style="font-family:Calibri;">[1]</span><span style="font-family:宋体;">处首先计算当前进程还剩的虚拟内存空间大小， </span><span style="font-family:Calibri;">[2]</span><span style="font-family:宋体;">处使用</span><span style="font-family:Calibri;">random</span><span style="font-family:宋体;">函数产生了一个页面对齐的随机数，然后与</span></span><span style="font-family:Calibri;font-size:14px;">addr_space_size</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">取模，在</span>64<span style="font-family:宋体;">位下，</span></span><span style="font-family:Calibri;font-size:14px;">addr_space_size</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">的取值可能非常大，</span> <span style="font-family:宋体;">所以</span>xnu<span style="font-family:宋体;">尝试最多</span><span style="font-family:Calibri;">1000</span><span style="font-family:宋体;">次循环来找到一个合适的地址空间。使用这样的算法，</span><span style="font-family:Calibri;">offset</span><span style="font-family:宋体;">的可控性很差， 还有可能因为随机数的问题导致整个</span><span style="font-family:Calibri;">mmap</span><span style="font-family:宋体;">动作失败，我觉得后续</span><span style="font-family:Calibri;">xnu</span><span style="font-family:宋体;">的内核工程师应该会改进这个算法。</span></span></p>



<p><a href="2247483725">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=fef0c8bd&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg4NjU1NDU4MA%3D%3D%26mid%3D2247483725%26idx%3D1%26sn%3Db37b02c59924474ccc97ac79b7a6a274%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Mon, 01 Feb 2021 12:56:00 +0800</pubDate>
    </item>
    <item>
      <title>XNU kauth子系统解读</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg4NjU1NDU4MA==&amp;mid=2247483720&amp;idx=1&amp;sn=c96728b68781eef0e3d1e7fa68a9683f</link>
      <description>全网最详细的XNU kauth实现解读</description>
      <content:encoded><![CDATA[<p>
原创 <span>wzt</span> <span>2021-01-28 11:32</span> <span style="display: inline-block;"></span>
</p>

<p>全网最详细的XNU kauth实现解读</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=1df55b35&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F4iaJia7Cvd3PBNmx2EbvvrweJJtzPxhRbqF9QYapSwkmmiawjho3lnLNVcg7ENTsUWrzgT3EU668OD9YkgJLP2p4A%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<h2 style="margin-left:0;text-indent:0;"><span style="font-family:Arial;font-weight:bold;font-size:21px;">1.1 </span><strong><span style="font-family: 黑体;font-size: 21px;"><span style="font-family:黑体;">简介</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">XNU<span style="font-family:宋体;">将进程凭证</span><span style="font-family:Calibri;">credential</span><span style="font-family:宋体;">、文件系统</span><span style="font-family:Calibri;">acl</span><span style="font-family:宋体;">授权、进程和文件系统监控这几个安全功能抽象为一个安全框架，叫做</span><span style="font-family:Calibri;">kauth</span><span style="font-family:宋体;">子系统。它的具体功能主要包含：</span></span></p><p><span style="font-family:宋体;font-size:14px;">- <span style="font-family:宋体;">进程凭证</span><span style="font-family:Calibri;">credential</span><span style="font-family:宋体;">的创建、更新、销毁。</span></span></p><p><span style="font-family:宋体;font-size:14px;">- <span style="font-family:宋体;">文件系统</span><span style="font-family:Calibri;">acl</span><span style="font-family:宋体;">的创建、评估、销毁。</span></span></p><p><span style="font-family:宋体;font-size:14px;">- <span style="font-family:宋体;">提供</span><span style="font-family:Calibri;">kauth scope</span><span style="font-family:宋体;">框架，对进程、文件系统做监控， 支持系统默认监控函数，提供</span><span style="font-family:Calibri;">kpi</span><span style="font-family:宋体;">接口，使得第三方内核扩展可以动态添加钩子。</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h2 style="margin-left:0;text-indent:0;"><span style="font-family:Arial;font-weight:bold;font-size:21px;">1.2 </span><strong><span style="font-family: 黑体;font-size: 21px;"><span style="font-family:黑体;">进程凭证维护</span></span></strong></h2><h3><strong><span style="font-family: 宋体;font-size: 21px;">1.2.1 <span style="font-family:宋体;">基本结构</span></span></strong></h3><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">XNU<span style="font-family:宋体;">与传统</span><span style="font-family:Calibri;">UNIX</span><span style="font-family:宋体;">的进程凭证</span><span style="font-family:Calibri;">cred</span><span style="font-family:宋体;">稍有不同。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">bsd/sys/ucred.h：</span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">ucred</span> {</span></span></code><code><span class="code-snippet_outer">        TAILQ_ENTRY(ucred)      cr_link; <span class="code-snippet__comment">/* never modify this without KAUTH_CRED_HASH_LOCK */</span></span></code><code><span class="code-snippet_outer">        u_long  cr_ref;                 <span class="code-snippet__comment">/* reference count */</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">posix_cred</span> {</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">uid_t</span>   cr_uid;                 <span class="code-snippet__comment">/* effective user id */</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">uid_t</span>   cr_ruid;                <span class="code-snippet__comment">/* real user id */</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">uid_t</span>   cr_svuid;               <span class="code-snippet__comment">/* saved user id */</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">short</span>   cr_ngroups;             <span class="code-snippet__comment">/* number of groups in advisory list */</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">gid_t</span>   cr_groups[NGROUPS];     <span class="code-snippet__comment">/* advisory group list */</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">gid_t</span>   cr_rgid;                <span class="code-snippet__comment">/* real group id */</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">gid_t</span>   cr_svgid;               <span class="code-snippet__comment">/* saved group id */</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">uid_t</span>   cr_gmuid;               <span class="code-snippet__comment">/* UID for group membership purposes */</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">int</span>     cr_flags;               <span class="code-snippet__comment">/* flags on credential */</span></span></code><code><span class="code-snippet_outer">} cr_posix;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">label</span>    *<span class="code-snippet__title">cr_label</span>;</span>      <span class="code-snippet__comment">/* MAC label */</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">au_session</span> <span class="code-snippet__title">cr_audit</span>;</span>             <span class="code-snippet__comment">/* user auditing data */</span></span></code><code><span class="code-snippet_outer">};</span></code></pre></section><p><span style="font-family:宋体;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">struct ucred<span style="font-family:宋体;">基本继承了</span><span style="font-family:Calibri;">BSD</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">ucred</span><span style="font-family:宋体;">结构，保留了</span><span style="font-family:Calibri;">MAC label</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">audit</span><span style="font-family:宋体;">审计成员，因为</span><span style="font-family:Calibri;">xnu</span><span style="font-family:宋体;">内核完全继承了</span><span style="font-family:Calibri;">BSD</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">MAC</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">audit</span><span style="font-family:宋体;">子系统能力。同时去掉了</span><span style="font-family:Calibri;">poison</span><span style="font-family:宋体;">成员， </span><span style="font-family:Calibri;">xnu</span><span style="font-family:宋体;">没有使用</span><span style="font-family:Calibri;">bsd jail</span><span style="font-family:宋体;">的功能，对于</span><span style="font-family:Calibri;">xnu</span><span style="font-family:宋体;">的沙箱功能，在后面的系列文章中在详细介绍。</span><span style="font-family:Calibri;">xnu ucred</span><span style="font-family:宋体;">仍然包含用户所在的组概念，成员</span><span style="font-family:Calibri;">cr_groups</span><span style="font-family:宋体;">数组长度为</span><span style="font-family:Calibri;">16</span><span style="font-family:宋体;">，是</span><span style="font-family:Calibri;">unix</span><span style="font-family:宋体;">家族中标准的用户组大小。除了</span><span style="font-family:Calibri;">cr_groups</span><span style="font-family:宋体;">，</span><span style="font-family:Calibri;">xnu</span><span style="font-family:宋体;">使用</span><span style="font-family:Calibri;">kauth</span><span style="font-family:宋体;">子系统扩展了用户所在组的概念，</span><span style="font-family:Calibri;">cr_groups</span><span style="font-family:宋体;">包含的仅是本地机器的用户组，</span><span style="font-family:Calibri;">Mac OS</span><span style="font-family:宋体;">可以作为服务器使用，</span><span style="font-family:Calibri;">kauth</span><span style="font-family:宋体;">建立了一种额外的扩展能力，可以将网络上的其他机器用户组包含到本地组里。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">XNU<span style="font-family:宋体;">是一个混合的内核，</span><span style="font-family:Calibri;">mach</span><span style="font-family:宋体;">微内核部分控制内核的进程创建与调度功能， </span><span style="font-family:Calibri;">mach</span><span style="font-family:宋体;">的进程结构体包含了指向</span><span style="font-family:Calibri;">bsd</span><span style="font-family:宋体;">进程和线程结构体的指针，而</span><span style="font-family:Calibri;">cred</span><span style="font-family:宋体;">是</span><span style="font-family:Calibri;">BSD</span><span style="font-family:宋体;">内核的功能，自然包含在</span><span style="font-family:Calibri;">bsd</span><span style="font-family:宋体;">封装的进程和线程结构体里，它们之间的数据结构体关系如下：</span></span></p><p><span style="font-family:宋体;font-size:14px;"> </span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.7124542124542125" data-s="300,640" style="" data-type="png" data-w="546" src="https://wechat2rss.xlab.app/img-proxy/?k=baf07d33&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F4iaJia7Cvd3PBNmx2EbvvrweJJtzPxhRbqURibqwRtGDMBc1c2aibR8TiaSxnTDCJWIsrvns6ISMRXWibc1xfKPHJY4w%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="z-index:1;margin-left:301.4000px;margin-top:10.1333px;width:242.0000px;height:118.0000px;"></span><span style="z-index:1;margin-left:21.4000px;margin-top:10.1333px;width:210.0000px;height:118.0000px;"><br/></span></p><p><span style="font-family:Calibri;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">内核通过</span>current_thread()<span style="font-family:宋体;">宏来获取</span><span style="font-family:Calibri;">mach</span><span style="font-family:宋体;">层的</span><span style="font-family:Calibri;">struct thread</span><span style="font-family:宋体;">指针，以</span><span style="font-family:Calibri;">i386</span><span style="font-family:宋体;">架构为例：</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">osfmk/i386/cpu_data.h</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">define</span> current_thread_fast()           get_active_thread()</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">define</span> current_thread()                current_thread_fast()</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">inline</span> __<span class="code-snippet__function">pure2 thread_t</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">get_active_thread</span><span class="code-snippet__params">(<span class="code-snippet__keyword">void</span>)</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        CPU_DATA_GET(cpu_active_thread,<span class="code-snippet__keyword">thread_t</span>)</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">define</span> CPU_DATA_GET(member,type)                                       \</span></span></code><code><span class="code-snippet_outer">        type ret;                                                       \</span></code><code><span class="code-snippet_outer">        __asm__ volatile (<span class="code-snippet__meta-string">&#34;mov %%gs:%P1,%0&#34;</span>                             \</span></code><code><span class="code-snippet_outer">                : <span class="code-snippet__meta-string">&#34;=r&#34;</span> (ret)                                            \</span></code><code><span class="code-snippet_outer">                : <span class="code-snippet__meta-string">&#34;i&#34;</span> (offsetof(cpu_data_t,member)));                   \</span></code><code><span class="code-snippet_outer">        return ret；</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">typedef</span> <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">cpu_data</span></span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">thread_t</span>                cpu_active_thread;</span></code><code><span class="code-snippet_outer">} <span class="code-snippet__keyword">cpu_data_t</span>;</span></code></pre></section><p><span style="font-family:Calibri;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;">cpu_data_t</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">结构体里的</span></span><span style="font-family:Calibri;font-size:14px;">cpu_active_thread</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">成员指向的就是当前</span>cpu<span style="font-family:宋体;">指向的</span><span style="font-family:Calibri;">mac thread</span><span style="font-family:宋体;">指针， 通过</span><span style="font-family:Calibri;">offsetof</span><span style="font-family:宋体;">宏计算处它的偏移，在</span><span style="font-family:Calibri;">i386</span><span style="font-family:宋体;">下</span><span style="font-family:Calibri;">%gs:offset</span><span style="font-family:宋体;">保存的就是它的地址。</span><span style="font-family:Calibri;">X64</span><span style="font-family:宋体;">下保存在</span><span style="font-family:Calibri;">%fs:offset</span><span style="font-family:宋体;">。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">内核通过</span>get_bsdthread_info<span style="font-family:宋体;">函数获取</span><span style="font-family:Calibri;">mac thread</span><span style="font-family:宋体;">指向的</span><span style="font-family:Calibri;">bsd thread</span><span style="font-family:宋体;">指针：</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">osfmk/kern/bsd_kern.<span class="code-snippet__function">c</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">void</span> *<span class="code-snippet__title">get_bsdthread_info</span><span class="code-snippet__params">(<span class="code-snippet__keyword">thread_t</span> th)</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span>(th-&gt;uthread);</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:Calibri;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">内核通过</span></span><span style="font-family:Calibri;font-size:14px;">get_threadtask</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">函数获取</span>mac thread<span style="font-family:宋体;">指向的</span><span style="font-family:Calibri;">mac task</span><span style="font-family:宋体;">指针，然后就可以通过</span><span style="font-family:Calibri;">mac task</span><span style="font-family:宋体;">找到</span><span style="font-family:Calibri;">bsd</span><span style="font-family:宋体;">进程的</span><span style="font-family:Calibri;">proc</span><span style="font-family:宋体;">指针。</span></span><span style="font-family: Calibri;font-size: 14px;"> </span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">osfmk/kern/bsd_kern.<span class="code-snippet__function">c</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">task_t  <span class="code-snippet__title">get_threadtask</span><span class="code-snippet__params">(<span class="code-snippet__keyword">thread_t</span> th)</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span>(th-&gt;task);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">void</span>  *<span class="code-snippet__title">get_bsdtask_info</span><span class="code-snippet__params">(<span class="code-snippet__keyword">task_t</span> t)</span></span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span>(t-&gt;bsd_info);</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:Calibri;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">内核通过</span>kauth_cred_get<span style="font-family:宋体;">函数获取进程的</span><span style="font-family:Calibri;">cred</span><span style="font-family:宋体;">结构指针，根据以上结构信息也就不难理解了。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">bsd/kern/kern_credential.<span class="code-snippet__function">c</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">kauth_cred_t</span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">kauth_cred_get</span><span class="code-snippet__params">(<span class="code-snippet__keyword">void</span>)</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">proc</span> *<span class="code-snippet__title">p</span>;</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">uthread</span> *<span class="code-snippet__title">uthread</span>;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        uthread = get_bsdthread_info(current_thread());</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (uthread == <span class="code-snippet__literal">NULL</span>)</span></code><code><span class="code-snippet_outer">                panic(<span class="code-snippet__string">&#34;thread wants credential but has no BSD thread info&#34;</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (uthread-&gt;uu_ucred == NOCRED) {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> ((p = (<span class="code-snippet__keyword">proc_t</span>) get_bsdtask_info(get_threadtask(current_thread()))) == <span class="code-snippet__literal">NULL</span>)</span></code><code><span class="code-snippet_outer">                        panic(<span class="code-snippet__string">&#34;thread wants credential but has no BSD process&#34;</span>);</span></code><code><span class="code-snippet_outer">                uthread-&gt;uu_ucred = kauth_cred_proc_ref(p);</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span>(uthread-&gt;uu_ucred);</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:Calibri;font-size:14px;"></span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><h3><strong><span style="font-family: 宋体;font-size: 21px;">1.2.2 cred<span style="font-family:宋体;">维护</span></span></strong></h3><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">XNU<span style="font-family:宋体;">对于进程</span><span style="font-family:Calibri;">cred</span><span style="font-family:宋体;">的维护与</span><span style="font-family:Calibri;">BSD</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">linux</span><span style="font-family:宋体;">有所不同， 它将每个进程的</span><span style="font-family:Calibri;">cred</span><span style="font-family:宋体;">缓存在一个</span><span style="font-family:Calibri;">hash</span><span style="font-family:宋体;">表里，对于复制</span><span style="font-family:Calibri;">cred</span><span style="font-family:宋体;">等操作，可以通过引用计数来实现，在它的代码注释中提到这种优化对于一个桌面系统来讲，可以至少节省</span><span style="font-family:Calibri;">200k</span><span style="font-family:宋体;">左右的内存。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h3><strong><span style="font-family: 宋体;font-size: 21px;">1.2.3 <span style="font-family:宋体;">组扩展机制</span></span></strong></h3><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">前面提到</span>xnu<span style="font-family:宋体;">扩展了</span><span style="font-family:Calibri;">bsd</span><span style="font-family:宋体;">的用户组管理机制，在内核中叫做</span><span style="font-family:Calibri;">kauth resolver</span><span style="font-family:宋体;">机制， 在</span><span style="font-family:Calibri;">kauth</span><span style="font-family:宋体;">初始化时，建立了几个队列，当内核使用</span><span style="font-family:Calibri;">cred</span><span style="font-family:宋体;">进行用户组授权的过程中， 将本次请求封装为一个</span><span style="font-family:Calibri;">worker</span><span style="font-family:宋体;">，加入相应的队列中等待用户态进程进行处理。</span><span style="font-family:Calibri;">xnu</span><span style="font-family:宋体;">增加了一个系统调用</span><span style="font-family:Calibri;">identitysvc</span><span style="font-family:宋体;">，用户进程使用这个系统调用与</span><span style="font-family:Calibri;">kauth</span><span style="font-family:宋体;">通讯，比如获取等待队列中的</span><span style="font-family:Calibri;">worker</span><span style="font-family:宋体;">，然后在用户态进行处理。用户组涉及到的处理逻辑相对复杂，</span><span style="font-family:Calibri;">xnu</span><span style="font-family:宋体;">直接引用了</span><span style="font-family:Calibri;">windows nt</span><span style="font-family:宋体;">内核的</span><span style="font-family:Calibri;">sid</span><span style="font-family:宋体;">概念来完善</span><span style="font-family:Calibri;">kuath</span><span style="font-family:宋体;">授权系统。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h4><strong><span style="font-family: 黑体;font-size: 19px;">1.2.3.1 kauth resolver<span style="font-family:黑体;">机制初始化</span></span></strong></h4><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer">bsd/kern/kern_authorization.<span class="code-snippet__function">c</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">void</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">kauth_init</span>(<span class="code-snippet__params"><span class="code-snippet__keyword">void</span></span>)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> CONFIG_EXT_RESOLVER</span></span></code><code><span class="code-snippet_outer">        kauth_identity_init();[<span class="code-snippet__number">1</span>]</span></code><code><span class="code-snippet_outer">        kauth_groups_init();[<span class="code-snippet__number">2</span>]</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> CONFIG_EXT_RESOLVER</span></span></code><code><span class="code-snippet_outer">        kauth_resolver_init();[<span class="code-snippet__number">3</span>]</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:Calibri;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">Kauth_init<span style="font-family:宋体;">在初始时</span><span style="font-family:Calibri;">[1]</span><span style="font-family:宋体;">处调用</span></span><span style="font-family:Calibri;font-size:14px;">kauth_identity_init()</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">初始化</span>kauth_identities<span style="font-family:宋体;">链表，每个节点是</span><span style="font-family:Calibri;">struct kauth_identity</span><span style="font-family:宋体;">结构体，这个链表用来缓存</span><span style="font-family:Calibri;">cred</span><span style="font-family:宋体;">的身份信息，因为如果每次身份验证时都要用户态进程参与，那么效率将会非常低，</span><span style="font-family:Calibri;">kauth</span><span style="font-family:宋体;">在每次用户态验证完时，将验证成功的身份信息缓存在</span><span style="font-family:Calibri;">kauth_identities</span><span style="font-family:宋体;">链表里，下次验证时将在缓存里进行搜索，如果没有匹配到，在通知用户态进程处理。</span><span style="font-family:Calibri;">[2]</span><span style="font-family:宋体;">处的</span></span><span style="font-family:Calibri;font-size:14px;">kauth_groups_init()</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">函数功能机理与上述一致。</span>[3]<span style="font-family:宋体;">处的</span></span><span style="font-family:Calibri;font-size:14px;">kauth_resolver_init</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">函数初始化了三个队列，分别为</span>kauth_resolver_unsubmitted<span style="font-family:宋体;">、</span><span style="font-family:Calibri;">kauth_resolver_submitted</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">kauth_resolver_done</span><span style="font-family:宋体;">。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h4><strong><span style="font-family: 黑体;font-size: 19px;">1.2.3.2 identitysvc<span style="font-family:黑体;">系统调用</span></span></strong></h4><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">用户态进程通过调用</span>identitysvc<span style="font-family:宋体;">系统调用在内核中进行注册，更新缓存大小、获取处理任务以及发送任务的处理结果。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">先来看下用户进程的注册过程。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer">bsd/kern/kern_credential.<span class="code-snippet__function">c</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">int</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">identitysvc</span>(<span class="code-snippet__params">__unused <span class="code-snippet__keyword">struct</span> proc *p, <span class="code-snippet__keyword">struct</span> identitysvc_args *uap, __unused int32_t *retval</span>)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">if</span> (opcode == KAUTH_EXTLOOKUP_REGISTER) {</span></code><code><span class="code-snippet_outer">                new_id = current_proc()-&gt;p_pid;</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> ((error = kauth_authorize_generic(kauth_cred_get(), KAUTH_GENERIC_ISSUSER)) != <span class="code-snippet__number">0</span>) {                                            [<span class="code-snippet__number">1</span>]</span></code><code><span class="code-snippet_outer">                        KAUTH_DEBUG(<span class="code-snippet__string">&#34;RESOLVER - pid %d refused permission to become identity resolver&#34;</span>, new_id);</span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">return</span>(error);</span></code><code><span class="code-snippet_outer">                }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> (kauth_resolver_identity != new_id) {[<span class="code-snippet__number">2</span>]</span></code><code><span class="code-snippet_outer">                        kauth_resolver_identity = new_id;[<span class="code-snippet__number">3</span>]</span></code><code><span class="code-snippet_outer">                        kauth_resolver_registered = <span class="code-snippet__number">1</span>;</span></code><code><span class="code-snippet_outer">                        wakeup(&amp;kauth_resolver_unsubmitted);[<span class="code-snippet__number">4</span>]</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:宋体;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">当来自用户空间的请求码为</span></span><span style="font-family:Calibri;font-size:14px;">KAUTH_EXTLOOKUP_REGISTER</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">时，</span> <span style="font-family:宋体;">在</span>[1]<span style="font-family:宋体;">处调用  </span></span><span style="font-family:Calibri;font-size:14px;">kauth_authorize_generic</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">，</span> <span style="font-family:宋体;">这是后面将要讲到的</span>kauth scope<span style="font-family:宋体;">监控机制，当前内核的默认授权只是检测当前进程</span><span style="font-family:Calibri;">uid</span><span style="font-family:宋体;">是不是为</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">， 也就是说只有</span><span style="font-family:Calibri;">root</span><span style="font-family:宋体;">权限用户才可以注册。</span><span style="font-family:Calibri;">[2]</span><span style="font-family:宋体;">处判断当前进程和之前注册的进程号是否相同，如果不相同就会用当前进程号替换原来的进程号</span></span><span style="font-family:Calibri;font-size:14px;">kauth_resolver_identity</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">，然后在</span>[4]<span style="font-family:宋体;">处唤醒</span></span><span style="font-family:Calibri;font-size:14px;">kauth_resolver_unsubmitted</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">等待队列上的进程。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">我们看到用户进程的注册过程相当简单，这里就会有几个安全问题。所有</span>root<span style="font-family:宋体;">进程都可以进行注册，</span><span style="font-family:Calibri;">linux</span><span style="font-family:宋体;">使用了</span><span style="font-family:Calibri;">capability</span><span style="font-family:宋体;">进一步将</span><span style="font-family:Calibri;">root</span><span style="font-family:宋体;">权限进行了划分， 比如</span><span style="font-family:Calibri;">auditd</span><span style="font-family:宋体;">的注册就需要有</span><span style="font-family:Calibri;">CAP_NET_ADMIN</span><span style="font-family:宋体;">这个能力才可以。而</span><span style="font-family:Calibri;">XNU</span><span style="font-family:宋体;">并没有继承</span><span style="font-family:Calibri;">BSD</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">capability</span><span style="font-family:宋体;">能力模型以及</span><span style="font-family:Calibri;">privilege</span><span style="font-family:宋体;">特权模型，这使得它对内核权限的控制就没有那么细致化。其次新的用户进程直接就可以替换老的用户进程，并没有使用一些可信验证手段， 这使得任何的恶意</span><span style="font-family:Calibri;">root</span><span style="font-family:宋体;">进程都可以对其进行替换和仿冒，这样身份验证机制就形同虚设了。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">我们在来看下用户进程是如何从内核获取任务的。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">bsd/kern/kern_credential.<span class="code-snippet__function">c</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">int</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">identitysvc</span><span class="code-snippet__params">(__unused struct proc *p, struct identitysvc_args *uap, __unused <span class="code-snippet__keyword">int32_t</span> *retval)</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (opcode &amp; KAUTH_EXTLOOKUP_WORKER) {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> ((error = kauth_resolver_getwork(message)) != <span class="code-snippet__number">0</span>)</span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">return</span>(error);</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">int</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">kauth_resolver_getwork</span><span class="code-snippet__params">(<span class="code-snippet__keyword">user_addr_t</span> message)</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">kauth_resolver_work</span> *<span class="code-snippet__title">workp</span>;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">while</span> ((workp = TAILQ_FIRST(&amp;kauth_resolver_unsubmitted)) == <span class="code-snippet__literal">NULL</span>) {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">thread_t</span> thread = current_thread();</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">uthread</span> *<span class="code-snippet__title">ut</span> = <span class="code-snippet__title">get_bsdthread_info</span>(<span class="code-snippet__title">thread</span>);</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">                ut-&gt;uu_save.uus_kauth.message = message;</span></code><code><span class="code-snippet_outer">                error = msleep0(&amp;kauth_resolver_unsubmitted, kauth_resolver_mtx, PCATCH, <span class="code-snippet__string">&#34;GRGetWork&#34;</span>, <span class="code-snippet__number">0</span>, kauth_resolver_getwork_continue);</span></code><code><span class="code-snippet_outer">                KAUTH_RESOLVER_UNLOCK();</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> (!kauth_resolver_identity) {</span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__built_in">printf</span>(<span class="code-snippet__string">&#34;external resolver died&#34;</span>);</span></code><code><span class="code-snippet_outer">                        error = KAUTH_RESOLVER_FAILED_ERRCODE;</span></code><code><span class="code-snippet_outer">                }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">return</span>(error);</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> kauth_resolver_getwork2(message);</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;">kauth_resolver_getwork</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">函数用户获取内核任务，</span> <span style="font-family:宋体;">首先判断</span></span><span style="font-family:Calibri;font-size:14px;">kauth_resolver_unsubmitted</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">队列是否为空，这个队列保存的是内核发布的等待用户进程获取的任务节点，下一小节会对其进行描述。如果队列为空，就使用</span>msleep<span style="font-family:宋体;">进行睡眠，同时回调函数设置为</span></span><span style="font-family:Calibri;font-size:14px;">kauth_resolver_getwork_continue</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">，这个函数只是继续判断队列是否为空，然后递归调用自己。当队列不为空时，会调用</span></span><span style="font-family:Calibri;font-size:14px;">kauth_resolver_getwork2</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">。它从</span></span><span style="font-family:Calibri;font-size:14px;">kauth_resolver_unsubmitted</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">队列头取下一个节点，用</span>copyout<span style="font-family:宋体;">函数拷贝给用户空间的进程，然后将这个节点移入到</span><span style="font-family:Calibri;">kauth_resolver_submitted</span><span style="font-family:宋体;">队列，这样用户进程就获取了要进行身份验证的信息。</span></span><br/></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">当用户进程处理完毕后，处理结果要返回给内核。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer">bsd/kern/kern_credential.<span class="code-snippet__function">c</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">int</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">identitysvc</span>(<span class="code-snippet__params">__unused <span class="code-snippet__keyword">struct</span> proc *p, <span class="code-snippet__keyword">struct</span> identitysvc_args *uap, __unused int32_t *retval</span>)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (opcode &amp; KAUTH_EXTLOOKUP_RESULT) {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> ((error = kauth_resolver_complete(message)) != <span class="code-snippet__number">0</span>)</span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">return</span>(error);</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">int</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">kauth_resolver_complete</span>(<span class="code-snippet__params">user_addr_t message</span>)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> ((error = copyin(message, &amp;extl, <span class="code-snippet__keyword">sizeof</span>(extl))) != <span class="code-snippet__number">0</span>) {</span></code><code><span class="code-snippet_outer">                KAUTH_DEBUG(<span class="code-snippet__string">&#34;RESOLVER - error getting completed work\n&#34;</span>);</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">return</span>(error);</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (extl.el_result != KAUTH_EXTLOOKUP_FATAL) {</span></code><code><span class="code-snippet_outer">                TAILQ_FOREACH(workp, &amp;kauth_resolver_submitted, kr_link) {</span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">if</span> (workp-&gt;kr_seqno == extl.el_seqno) {</span></code><code><span class="code-snippet_outer">                                TAILQ_INSERT_TAIL(&amp;kauth_resolver_done, workp, kr_link);</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:宋体;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;">kauth_resolver_complete</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">通过</span>copyin<span style="font-family:宋体;">将用户信息拷贝到内核，然后遍历</span></span><span style="font-family:Calibri;font-size:14px;">kauth_resolver_submitted</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">队列，根据</span>seq<span style="font-family:宋体;">号找到对应的节点，更新处理信息，然后将这个节点移动到</span><span style="font-family:Calibri;">kauth_resolver_done</span><span style="font-family:宋体;">队列。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h4><strong><span style="font-family: 黑体;font-size: 19px;">1.2.3.3 cred<span style="font-family:黑体;">身份验证</span></span></strong></h4><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">当涉及到</span>cred<span style="font-family:宋体;">的身份验证时，</span><span style="font-family:Calibri;">kauth</span><span style="font-family:宋体;">调用</span><span style="font-family:Calibri;">kauth_cred_cache_lookup</span><span style="font-family:宋体;">函数进行处理。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer">bsd/kern/kern_credential.<span class="code-snippet__function">c</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">int</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">kauth_cred_cache_lookup</span>(<span class="code-snippet__params"><span class="code-snippet__keyword">int</span> <span class="code-snippet__keyword">from</span>, <span class="code-snippet__keyword">int</span> to, <span class="code-snippet__keyword">void</span> *src, <span class="code-snippet__keyword">void</span> *dst</span>)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">switch</span>(<span class="code-snippet__keyword">from</span>) {</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">case</span> KI_VALID_UID:[<span class="code-snippet__number">1</span>]</span></code><code><span class="code-snippet_outer">                error = kauth_identity_find_uid(*(uid_t *)src, &amp;ki, namebuf);</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> (expired) {</span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">if</span> (!expired(&amp;ki)) {[<span class="code-snippet__number">2</span>]</span></code><code><span class="code-snippet_outer">                                KAUTH_DEBUG(<span class="code-snippet__string">&#34;CACHE - entry valid, unexpired&#34;</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        error = kauth_resolver_submit(&amp;el, extend_data);[<span class="code-snippet__number">3</span>]</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (error == <span class="code-snippet__number">0</span>) {</span></code><code><span class="code-snippet_outer">                kauth_identity_updatecache(&amp;el, &amp;ki, extend_data);[<span class="code-snippet__number">4</span>]</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:宋体;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">kauth<span style="font-family:宋体;">在</span><span style="font-family:Calibri;">kauth_identities cache</span><span style="font-family:宋体;">中维护着一个转换列表，</span><span style="font-family:Calibri;">cred</span><span style="font-family:宋体;">中的</span><span style="font-family:Calibri;">uid</span><span style="font-family:宋体;">可以对应</span><span style="font-family:Calibri;">kauth_identities</span><span style="font-family:宋体;">中的</span><span style="font-family:Calibri;">guid</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">ntsid</span><span style="font-family:宋体;">等等。比如转换类型为</span></span><span style="font-family:Calibri;font-size:14px;">KI_VALID_UID</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">，则在</span>[1]<span style="font-family:宋体;">处调用</span></span><span style="font-family:Calibri;font-size:14px;">kauth_identity_find_uid</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">，在</span>cache<span style="font-family:宋体;">中进行搜索。找到后，还要在</span><span style="font-family:Calibri;">[2]</span><span style="font-family:宋体;">处进行验证身份信息是否过</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="php"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">static</span> int</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">kauth_resolver_submit(struct kauth_identity_extlookup *lkp, uint64_t extend_data)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        struct kauth_resolver_work *workp, *killp;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        MALLOC(workp, struct kauth_resolver_work *, sizeof(*workp), M_KAUTH, M_WAITOK); [<span class="code-snippet__number">1</span>]</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (workp == <span class="code-snippet__keyword">NULL</span>)</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">return</span>(ENOMEM);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        workp-&gt;kr_work = *lkp;</span></code><code><span class="code-snippet_outer">        workp-&gt;kr_extend = extend_data;</span></code><code><span class="code-snippet_outer">        workp-&gt;kr_refs = <span class="code-snippet__number">1</span>;</span></code><code><span class="code-snippet_outer">        workp-&gt;kr_flags = KAUTH_REQUEST_UNSUBMITTED;</span></code><code><span class="code-snippet_outer">        workp-&gt;kr_result = <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">        KAUTH_RESOLVER_LOCK();</span></code><code><span class="code-snippet_outer">        workp-&gt;kr_seqno = workp-&gt;kr_work.el_seqno = kauth_resolver_sequence++;</span></code><code><span class="code-snippet_outer">        workp-&gt;kr_work.el_result = KAUTH_EXTLOOKUP_INPROG;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">TAILQ_INSERT_TAIL(&amp;kauth_resolver_unsubmitted, workp, kr_link);    [<span class="code-snippet__number">2</span>]</span></code><code><span class="code-snippet_outer">    wakeup_one((caddr_t)&amp;kauth_resolver_unsubmitted);   [<span class="code-snippet__number">3</span>]</span></code><code><span class="code-snippet_outer">    error = __KERNEL_IS_WAITING_ON_EXTERNAL_CREDENTIAL_RESOLVER__(workp); [<span class="code-snippet__number">4</span>]</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span> (error == <span class="code-snippet__number">0</span>)</span></code><code><span class="code-snippet_outer">    *lkp = workp-&gt;kr_work;   [<span class="code-snippet__number">5</span>]</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">期。如果没找到会在</span><span style="font-family:Calibri;">[3]</span><span style="font-family:宋体;">处调用</span></span><span style="font-family:Calibri;font-size:14px;">kauth_resolver_submit</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">，</span> <span style="font-family:宋体;">将当前处理信息封装为一个</span>struct kauth_identity_extlookup<span style="font-family:宋体;">结构体发送到等待队列中进行处理。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">[1] </span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">处封装为一个</span></span><span style="font-family:Calibri;font-size:14px;">struct kauth_resolver_work</span><span style="font-family:宋体;font-size:14px;"> worker<span style="font-family:宋体;">节点，在</span><span style="font-family:Calibri;">[2]</span><span style="font-family:宋体;">处挂接到</span><span style="font-family:Calibri;">kauth_resolver_unsubmitted</span><span style="font-family:宋体;">队列末尾，在</span><span style="font-family:Calibri;">[3]</span><span style="font-family:宋体;">处唤醒在这个等待队列上睡眠的进程，通常为用户态的</span><span style="font-family:Calibri;">memberd</span><span style="font-family:宋体;">守护进程。然后在</span><span style="font-family:Calibri;">[4]</span><span style="font-family:宋体;">处调用 </span><span style="font-family:Calibri;">__KERNEL_IS_WAITING_ON_EXTERNAL_CREDENTIAL_RESOLVER__</span><span style="font-family:宋体;">函数，它一直调用</span><span style="font-family:Calibri;">msleep</span><span style="font-family:宋体;">睡眠</span><span style="font-family:Calibri;">kauth_resolver_timeout</span><span style="font-family:宋体;">秒，再次被唤醒后，检查</span><span style="font-family:Calibri;">worker</span><span style="font-family:宋体;">的状态是否为</span><span style="font-family:Calibri;">KAUTH_REQUEST_DONE</span><span style="font-family:宋体;">，如果是则函数返回，否则继续睡眠重复上述行为。当</span><span style="font-family:Calibri;">worker</span><span style="font-family:宋体;">被处理完毕后，在</span><span style="font-family:Calibri;">[5]</span><span style="font-family:宋体;">处保存更新后的信息。这个信息是用户态进程处理完毕后使用</span><span style="font-family:Calibri;">identitysvc</span><span style="font-family:宋体;">系统调用进行同步的。回到</span></span><span style="font-family:Calibri;font-size:14px;">kauth_cred_cache_lookup</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">函数，它将调用</span></span><span style="font-family:Calibri;font-size:14px;">kauth_identity_updatecache</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">在缓存中更新相关信息。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h3><strong><span style="font-family: 宋体;font-size: 21px;">1.2.4 <span style="font-family:宋体;">进程和文件系统监控</span></span></strong></h3><h4><strong><span style="font-family: 黑体;font-size: 19px;">1.2.4.1 kauth scope<span style="font-family:黑体;">框架</span></span></strong></h4><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">Kauth<span style="font-family:宋体;">定义了一个</span><span style="font-family:Calibri;">scope</span><span style="font-family:宋体;">监控框架，提供默认和第三方内核扩展回调函数支持，可以对进程和文件系统的关键行为进行监控。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">监控类型有几下几种：</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">bsd/sys/kauth.h</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">define</span> KAUTH_SCOPE_GENERIC     <span class="code-snippet__meta-string">&#34;com.apple.kauth.generic&#34;</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">define</span> KAUTH_SCOPE_PROCESS     <span class="code-snippet__meta-string">&#34;com.apple.kauth.process&#34;</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">define</span> KAUTH_SCOPE_VNODE       <span class="code-snippet__meta-string">&#34;com.apple.kauth.vnode&#34;</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">define</span> KAUTH_SCOPE_FILEOP      <span class="code-snippet__meta-string">&#34;com.apple.kauth.fileop&#34;</span></span></span></code></pre></section><p><span style="font-family:Calibri;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;">KAUTH_SCOPE_GENERIC</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">是通用的内核事件监控函数，比如在前面章节讲到的用户态进程注册</span>kauth resovler<span style="font-family:宋体;">时就调用了它的默认监控函数，只判断进程的</span><span style="font-family:Calibri;">uid</span><span style="font-family:宋体;">号是否为</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">。</span></span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;">KAUTH_SCOPE_PROCESS</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">提供进程事件的相关监控，目前只对能否向目标进程发送信号和是否有调试权限做了监控。</span></span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;">KAUTH_SCOPE_VNODE</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">提供了对</span>vnode<span style="font-family:宋体;">的权限检查以及</span><span style="font-family:Calibri;">acl</span><span style="font-family:宋体;">评估功能。</span></span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;">KAUTH_SCOPE_FILEOP</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">提供了对文件状态和属性更改的监控，它类似于</span>linux<span style="font-family:宋体;">的</span><span style="font-family:Calibri;">fsnotify</span><span style="font-family:宋体;">文件系统监控框架。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">Kauth<span style="font-family:宋体;">子系统定义了</span><span style="font-family:Calibri;">struct kauth_scope</span><span style="font-family:宋体;">结构：</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">define</span> KAUTH_SCOPE_MAX_LISTENERS  15</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">kauth_scope</span> {</span></span></code><code><span class="code-snippet_outer">        TAILQ_ENTRY(kauth_scope)        ks_link;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">volatile</span> <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">kauth_local_listener</span>  <span class="code-snippet__title">ks_listeners</span>[<span class="code-snippet__title">KAUTH_SCOPE_MAX_LISTENERS</span>];</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">const</span> <span class="code-snippet__keyword">char</span> *                            ks_identifier;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">kauth_scope_callback_t</span>          ks_callback;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">void</span> *                                          ks_idata;</span></code><code><span class="code-snippet_outer">        u_int                                           ks_flags;</span></code><code><span class="code-snippet_outer">};</span></code></pre></section><p><span style="font-family:Calibri;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;">ks_callback</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">即为默认的</span>callback<span style="font-family:宋体;">函数。</span></span><span style="font-family:Calibri;font-size:14px;">ks_listeners</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">为第三方内核扩展定义的</span>callback<span style="font-family:宋体;">函数。每个</span><span style="font-family:Calibri;">scope</span><span style="font-family:宋体;">最多有</span><span style="font-family:Calibri;">15</span><span style="font-family:宋体;">个扩展回调函数。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">kauth_local_listener</span> {</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">kauth_listener_t</span>                        kll_listenerp;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">kauth_scope_callback_t</span>          kll_callback;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">void</span> *                                          kll_idata;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:Calibri;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">内核使用</span>kauth_register_scope<span style="font-family:宋体;">注册一个</span><span style="font-family:Calibri;">scope</span><span style="font-family:宋体;">。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">kauth_scope_t</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">kauth_register_scope(<span class="code-snippet__keyword">const</span> <span class="code-snippet__keyword">char</span> *identifier, <span class="code-snippet__keyword">kauth_scope_callback_t</span> callback, <span class="code-snippet__keyword">void</span> *idata)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">kauth_scope_t</span>           sp, tsp;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">kauth_listener_t</span>        klp;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> ((sp = kauth_alloc_scope(identifier, callback, idata)) == <span class="code-snippet__literal">NULL</span>)</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">return</span>(<span class="code-snippet__literal">NULL</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        KAUTH_SCOPELOCK();</span></code><code><span class="code-snippet_outer">        TAILQ_FOREACH(tsp, &amp;kauth_scopes, ks_link) {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> (<span class="code-snippet__built_in">strncmp</span>(tsp-&gt;ks_identifier, identifier,</span></code><code><span class="code-snippet_outer">                                        <span class="code-snippet__built_in">strlen</span>(tsp-&gt;ks_identifier) + <span class="code-snippet__number">1</span>) == <span class="code-snippet__number">0</span>) {</span></code><code><span class="code-snippet_outer">                        KAUTH_SCOPEUNLOCK();</span></code><code><span class="code-snippet_outer">                        FREE(sp, M_KAUTH);</span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">return</span>(<span class="code-snippet__literal">NULL</span>);</span></code><code><span class="code-snippet_outer">                }</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        TAILQ_INSERT_TAIL(&amp;kauth_scopes, sp, ks_link);</span></code><code><span class="code-snippet_outer">restart:</span></code><code><span class="code-snippet_outer">        TAILQ_FOREACH(klp, &amp;kauth_dangling_listeners, kl_link) {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> (<span class="code-snippet__built_in">strncmp</span>(klp-&gt;kl_identifier, sp-&gt;ks_identifier,</span></code><code><span class="code-snippet_outer">                                        <span class="code-snippet__built_in">strlen</span>(klp-&gt;kl_identifier) + <span class="code-snippet__number">1</span>) == <span class="code-snippet__number">0</span>) {</span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">if</span> (kauth_add_callback_to_scope(sp, klp) == <span class="code-snippet__number">0</span>) {</span></code><code><span class="code-snippet_outer">                                TAILQ_REMOVE(&amp;kauth_dangling_listeners, klp, kl_link);</span></code><code><span class="code-snippet_outer">                        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">else</span> {</span></code><code><span class="code-snippet_outer">                                <span class="code-snippet__keyword">break</span>;</span></code><code><span class="code-snippet_outer">                        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">goto</span> restart;</span></code><code><span class="code-snippet_outer">                }</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        KAUTH_SCOPEUNLOCK();</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span>(sp);</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:宋体;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">所有</span>scope<span style="font-family:宋体;">存在于</span><span style="font-family:Calibri;">kauth_scopes</span><span style="font-family:宋体;">链表，</span><span style="font-family:Calibri;">kauth_register_scope</span><span style="font-family:宋体;">首先根据名称搜索是否已经存在重名的</span><span style="font-family:Calibri;">scope</span><span style="font-family:宋体;">节点，存在直接返回。如果不存在的话，将其挂接于</span><span style="font-family:Calibri;">kauth_scopes</span><span style="font-family:宋体;">链表末尾。然后它遍历</span><span style="font-family:Calibri;">kauth_dangling_listeners</span><span style="font-family:宋体;">链表，这里保存的是备用的第三方回调函数节点</span><span style="font-family:Calibri;">kauth listener, </span><span style="font-family:宋体;">调用</span><span style="font-family:Calibri;">kauth_add_callback_to_scope</span><span style="font-family:宋体;">将其添加到对应的</span><span style="font-family:Calibri;">scope listener</span><span style="font-family:宋体;">数组里。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="php"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">static</span> int kauth_add_callback_to_scope(kauth_scope_t sp, kauth_listener_t klp)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        int             i；</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">for</span> (i = <span class="code-snippet__number">0</span>; i &lt; KAUTH_SCOPE_MAX_LISTENERS; i++) {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> (sp-&gt;ks_listeners[i].kll_listenerp == <span class="code-snippet__keyword">NULL</span>) {</span></code><code><span class="code-snippet_outer">                        sp-&gt;ks_listeners[i].kll_callback = klp-&gt;kl_callback;</span></code><code><span class="code-snippet_outer">                        sp-&gt;ks_listeners[i].kll_idata = klp-&gt;kl_idata;</span></code><code><span class="code-snippet_outer">                        sp-&gt;ks_listeners[i].kll_listenerp = klp;</span></code><code><span class="code-snippet_outer">                        sp-&gt;ks_flags |= KS_F_HAS_LISTENERS;</span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">return</span>(<span class="code-snippet__number">0</span>);</span></code><code><span class="code-snippet_outer">             }</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span>(ENOSPC);</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:Calibri;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">内核使用</span></span><span style="font-family:Calibri;font-size:14px;">kauth_listen_scope</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">函数注册一个第三方内核扩展</span>listener<span style="font-family:宋体;">到一个</span><span style="font-family:Calibri;">scope</span><span style="font-family:宋体;">上。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">kauth_listener_t</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">kauth_listen_scope(<span class="code-snippet__keyword">const</span> <span class="code-snippet__keyword">char</span> *identifier, <span class="code-snippet__keyword">kauth_scope_callback_t</span> callback, <span class="code-snippet__keyword">void</span> *idata)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">kauth_listener_t</span> klp;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">kauth_scope_t</span>   sp;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> ((klp = kauth_alloc_listener(identifier, callback, idata)) == <span class="code-snippet__literal">NULL</span>)</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">return</span>(<span class="code-snippet__literal">NULL</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        KAUTH_SCOPELOCK();</span></code><code><span class="code-snippet_outer">        TAILQ_FOREACH(sp, &amp;kauth_scopes, ks_link) {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> (<span class="code-snippet__built_in">strncmp</span>(sp-&gt;ks_identifier, identifier,</span></code><code><span class="code-snippet_outer">                                        <span class="code-snippet__built_in">strlen</span>(sp-&gt;ks_identifier) + <span class="code-snippet__number">1</span>) == <span class="code-snippet__number">0</span>) {</span></code><code><span class="code-snippet_outer">                     </span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">if</span> (kauth_add_callback_to_scope(sp, klp) == <span class="code-snippet__number">0</span>) {</span></code><code><span class="code-snippet_outer">                                KAUTH_SCOPEUNLOCK();</span></code><code><span class="code-snippet_outer">                                <span class="code-snippet__keyword">return</span>(klp);</span></code><code><span class="code-snippet_outer">                        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">                        KAUTH_SCOPEUNLOCK();</span></code><code><span class="code-snippet_outer">                        FREE(klp, M_KAUTH);</span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">return</span>(<span class="code-snippet__literal">NULL</span>);</span></code><code><span class="code-snippet_outer">                }</span></code><code><span class="code-snippet_outer">        } </span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        TAILQ_INSERT_TAIL(&amp;kauth_dangling_listeners, klp, kl_link);</span></code><code><span class="code-snippet_outer">        KAUTH_SCOPEUNLOCK();</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span>(klp);</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:Calibri;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">它的注册逻辑也非常简单，首先遍历</span></span><span style="font-family:Calibri;font-size:14px;">kauth_scopes</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">链表找到对应的</span>scope<span style="font-family:宋体;">，如果找到，就调用</span></span><span style="font-family:Calibri;font-size:14px;">kauth_add_callback_to_scope</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">将其加入</span>scope<span style="font-family:宋体;">的</span><span style="font-family:Calibri;">listener</span><span style="font-family:宋体;">数组里。如果没找到，将这个节点挂接于</span></span><span style="font-family:Calibri;font-size:14px;">kauth_dangling_listeners</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">备用链表中，</span> <span style="font-family:宋体;">当需要的</span>scope<span style="font-family:宋体;">被注册时，会自动从</span></span><span style="font-family:Calibri;font-size:14px;">kauth_dangling_listeners</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">链表中找到这个节点并挂接上去。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">在需要监控的内核路径中，</span> <span style="font-family:宋体;">会调用</span>kauth_authorize_action<span style="font-family:宋体;">函数。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">int</span></span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">kauth_authorize_action</span><span class="code-snippet__params">(<span class="code-snippet__keyword">kauth_scope_t</span> scope, <span class="code-snippet__keyword">kauth_cred_t</span> credential, <span class="code-snippet__keyword">kauth_action_t</span> action,</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">uintptr_t</span> arg0, <span class="code-snippet__keyword">uintptr_t</span> arg1, <span class="code-snippet__keyword">uintptr_t</span> arg2, <span class="code-snippet__keyword">uintptr_t</span> arg3)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">int</span> result, ret, i;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (scope-&gt;ks_callback != <span class="code-snippet__literal">NULL</span>)</span></code><code><span class="code-snippet_outer">                result = scope-&gt;ks_callback(credential, scope-&gt;ks_idata, action, arg0, arg1,</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">else</span></span></code><code><span class="code-snippet_outer">                result = KAUTH_RESULT_DEFER;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> ((scope-&gt;ks_flags &amp; KS_F_HAS_LISTENERS) != <span class="code-snippet__number">0</span>) {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">for</span> (i = <span class="code-snippet__number">0</span>; i &lt; KAUTH_SCOPE_MAX_LISTENERS; i++) {</span></code><code><span class="code-snippet_outer">                        ret = scope-&gt;ks_listeners[i].kll_callback(</span></code><code><span class="code-snippet_outer">                                        credential, scope-&gt;ks_listeners[i].kll_idata,</span></code><code><span class="code-snippet_outer">                                        action, arg0, arg1, arg2, arg3);</span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">if</span> ((ret == KAUTH_RESULT_DENY) ||</span></code><code><span class="code-snippet_outer">                                (result == KAUTH_RESULT_DEFER))</span></code><code><span class="code-snippet_outer">                                result = ret;</span></code><code><span class="code-snippet_outer">                }</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span>(result == KAUTH_RESULT_ALLOW ? <span class="code-snippet__number">0</span> : EPERM);</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:Calibri;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">首先它会调用默认的回调函数，然后如果此</span>scope<span style="font-family:宋体;">有</span><span style="font-family:Calibri;">listener</span><span style="font-family:宋体;">，则将依次调用</span><span style="font-family:Calibri;">listener</span><span style="font-family:宋体;">注册的回调函数， 算法有点类似</span><span style="font-family:Calibri;">acl</span><span style="font-family:宋体;">评估机制，如果有一个</span><span style="font-family:Calibri;">listener</span><span style="font-family:宋体;">拒绝的话就直接返回失败。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h4><strong><span style="font-family: 黑体;font-size: 19px;">1.2.4.2 <span style="font-family:黑体;">进程监控</span></span></strong></h4><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">Kauth<span style="font-family:宋体;">在初始化的时候调用</span><span style="font-family:Calibri;">kauth_scope_init</span><span style="font-family:宋体;">初始化三个监控类型的</span><span style="font-family:Calibri;">scope</span><span style="font-family:宋体;">。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">kauth_scope_init</span><span class="code-snippet__params">(<span class="code-snippet__keyword">void</span>)</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        kauth_scope_mtx = lck_mtx_alloc_init(kauth_lck_grp, <span class="code-snippet__number">0</span> <span class="code-snippet__comment">/*LCK_ATTR_NULL*/</span>);</span></code><code><span class="code-snippet_outer">        kauth_scope_process = kauth_register_scope(KAUTH_SCOPE_PROCESS, kauth_authorize_process_callback, <span class="code-snippet__literal">NULL</span>);</span></code><code><span class="code-snippet_outer">        kauth_scope_generic = kauth_register_scope(KAUTH_SCOPE_GENERIC, kauth_authorize_generic_callback, <span class="code-snippet__literal">NULL</span>);</span></code><code><span class="code-snippet_outer">        kauth_scope_fileop = kauth_register_scope(KAUTH_SCOPE_FILEOP, <span class="code-snippet__literal">NULL</span>, <span class="code-snippet__literal">NULL</span>);</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:Calibri;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">对于进程的监控，注册的默认回调函数为</span></span><span style="font-family:Calibri;font-size:14px;">kauth_authorize_process_callback</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">int</span></span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">kauth_authorize_process_callback</span><span class="code-snippet__params">(<span class="code-snippet__keyword">kauth_cred_t</span> credential, __unused <span class="code-snippet__keyword">void</span> *idata, <span class="code-snippet__keyword">kauth_action_t</span> action,</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">uintptr_t</span> arg0, <span class="code-snippet__keyword">uintptr_t</span> arg1, __unused <span class="code-snippet__keyword">uintptr_t</span> arg2, __unused <span class="code-snippet__keyword">uintptr_t</span> arg3)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">switch</span>(action) {</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">case</span> KAUTH_PROCESS_CANSIGNAL:</span></code><code><span class="code-snippet_outer">                panic(<span class="code-snippet__string">&#34;KAUTH_PROCESS_CANSIGNAL not implemented&#34;</span>);</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> (cansignal(current_proc(), credential, (struct proc *)arg0, (<span class="code-snippet__keyword">int</span>)arg1))</span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">return</span>(KAUTH_RESULT_ALLOW);</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">break</span>;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">case</span> KAUTH_PROCESS_CANTRACE:</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> (cantrace(current_proc(), credential, (<span class="code-snippet__keyword">proc_t</span>)arg0, (<span class="code-snippet__keyword">int</span> *)arg1))</span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">return</span>(KAUTH_RESULT_ALLOW);</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">break</span>;</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span>(KAUTH_RESULT_DEFER);</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:Calibri;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">回调函数非常简单，只判断进程是否有</span>trace<span style="font-family:宋体;">能力，对于是否能有发送信号的能力，</span><span style="font-family:Calibri;">xnu</span><span style="font-family:宋体;">内核开发者估计也没想好，</span><span style="font-family:Calibri;">panic</span><span style="font-family:宋体;">函数直接写在了</span><span style="font-family:Calibri;">cansignal</span><span style="font-family:宋体;">函数的前面。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h4><strong><span style="font-family: 黑体;font-size: 19px;">1.2.4.3 <span style="font-family:黑体;">文件状态监控</span></span></strong></h4><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">在</span></span><span style="font-family:Calibri;font-size:14px;">kauth_scope_init</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">初始化时，并没有对</span></span><span style="font-family:Calibri;font-size:14px;">KAUTH_SCOPE_FILEOP</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">类型的</span>scope<span style="font-family:宋体;">设置默认回调函数。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span></span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">kauth_scope_init</span><span class="code-snippet__params">(<span class="code-snippet__keyword">void</span>)</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        kauth_scope_fileop = kauth_register_scope(KAUTH_SCOPE_FILEOP, <span class="code-snippet__literal">NULL</span>, <span class="code-snippet__literal">NULL</span>);</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:Calibri;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">在文件状态发生变更的地方，都调用了</span>kauth_authorize_fileop<span style="font-family:宋体;">函数，它继而调用</span><span style="font-family:Calibri;">kauth_authorize_action</span><span style="font-family:宋体;">函数，由于</span></span><span style="font-family:Calibri;font-size:14px;">KAUTH_SCOPE_FILEOP</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">类型的</span>scope<span style="font-family:宋体;">没有默认回调函数，它将继续判断是否有加载第三方内核扩展的回调函数。对于文件系统状态监控，开发人员需要自己编写一个内核扩展注册</span><span style="font-family:Calibri;">listene</span><span style="font-family:宋体;">回调函数到</span><span style="font-family:Calibri;">scope</span><span style="font-family:宋体;">中才行，</span><span style="font-family:Calibri;">xnu</span><span style="font-family:宋体;">内核并没有提供默认的内核扩展。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">kauth_authorize_fileop<span style="font-family:宋体;">函数定义为：</span></span></p><p><span style="font-family:宋体;font-size:14px;">int</span></p><p><span style="font-family:Calibri;font-size:14px;">kauth_authorize_fileop(kauth_cred_t credential, kauth_action_t action, uintptr_t arg0, uintptr_t arg1)</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">；</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">内核在文件系统的不同路径调用它，最后两个参数在不同的调用路径对应不同的意义。内核注释代码中写的很详细：</span></span></p><p><span style="font-family:Calibri;font-size:14px;"> * arguments passed to KAUTH_FILEOP_OPEN listeners</span></p><p><span style="font-family:Calibri;font-size:14px;"> *              arg0 is pointer to vnode (vnode *) for given user path.</span></p><p><span style="font-family:Calibri;font-size:14px;"> *              arg1 is pointer to path (char *) passed in to open.</span></p><p><span style="font-family:Calibri;font-size:14px;"> * arguments passed to KAUTH_FILEOP_CLOSE listeners</span></p><p><span style="font-family:Calibri;font-size:14px;"> *              arg0 is pointer to vnode (vnode *) for file to be closed.</span></p><p><span style="font-family:Calibri;font-size:14px;"> *              arg1 is pointer to path (char *) of file to be closed.</span></p><p><span style="font-family:Calibri;font-size:14px;"> *              arg2 is close flags.</span></p><p><span style="font-family:Calibri;font-size:14px;"> * arguments passed to KAUTH_FILEOP_WILL_RENAME listeners</span></p><p><span style="font-family:Calibri;font-size:14px;"> *              arg0 is pointer to vnode (vnode *) of the file being renamed</span></p><p><span style="font-family:Calibri;font-size:14px;"> *              arg1 is pointer to the &#34;from&#34; path (char *)</span></p><p><span style="font-family:Calibri;font-size:14px;"> *              arg2 is pointer to the &#34;to&#34; path (char *)</span></p><p><span style="font-family:Calibri;font-size:14px;"> * arguments passed to KAUTH_FILEOP_RENAME listeners</span></p><p><span style="font-family:Calibri;font-size:14px;"> *              arg0 is pointer to &#34;from&#34; path (char *).</span></p><p><span style="font-family:Calibri;font-size:14px;"> *              arg1 is pointer to &#34;to&#34; path (char *).</span></p><p><span style="font-family:Calibri;font-size:14px;"> * arguments passed to KAUTH_FILEOP_EXCHANGE listeners</span></p><p><span style="font-family:Calibri;font-size:14px;"> *              arg0 is pointer to file 1 path (char *).</span></p><p><span style="font-family:Calibri;font-size:14px;"> *              arg1 is pointer to file 2 path (char *).</span></p><p><span style="font-family:Calibri;font-size:14px;"> * arguments passed to KAUTH_FILEOP_EXEC listeners</span></p><p><span style="font-family:Calibri;font-size:14px;"> *              arg0 is pointer to vnode (vnode *) for executable.</span></p><p><span style="font-family:Calibri;font-size:14px;"> *              arg1 is pointer to path (char *) to executable.</span></p><p><span style="font-family:Calibri;font-size:14px;"><br/></span></p><h3><strong><span style="font-family: 宋体;font-size: 21px;">1.2.4.4 <span style="font-family:宋体;">文件</span><span style="font-family:Calibri;">vnode</span><span style="font-family:宋体;">授权与</span><span style="font-family:Calibri;">acl</span><span style="font-family:宋体;">检查</span></span></strong></h3><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">对于文件</span>vnode<span style="font-family:宋体;">监控的</span><span style="font-family:Calibri;">kauth scope</span><span style="font-family:宋体;">注册是放在文件系统初始化进行的：</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">bsd/vfs/vfs_subr.<span class="code-snippet__function">c</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">void</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">vnode_authorize_init</span><span class="code-snippet__params">(<span class="code-snippet__keyword">void</span>)</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        vnode_scope = kauth_register_scope(KAUTH_SCOPE_VNODE, vnode_authorize_callback, <span class="code-snippet__literal">NULL</span>);</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">它注册的</span>callback<span style="font-family:宋体;">函数为</span></span><span style="font-family:Calibri;font-size:14px;">vnode_authorize_callback</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">。</span>vnode<span style="font-family:宋体;">的权限检查包括以下几个：</span></span></p><p><span style="font-family:宋体;font-size:14px;">#define KAUTH_VNODE_READ_DATA                   (1&lt;&lt;1)</span></p><p><span style="font-family:宋体;font-size:14px;">#define KAUTH_VNODE_WRITE_DATA                  (1&lt;&lt;2)</span></p><p><span style="font-family:宋体;font-size:14px;">#define KAUTH_VNODE_EXECUTE                     (1&lt;&lt;3)</span></p><p><span style="font-family:宋体;font-size:14px;">#define KAUTH_VNODE_DELETE                      (1&lt;&lt;4)</span></p><p><span style="font-family:宋体;font-size:14px;">#define KAUTH_VNODE_APPEND_DATA                 (1&lt;&lt;5)</span></p><p><span style="font-family:宋体;font-size:14px;">#define KAUTH_VNODE_DELETE_CHILD                (1&lt;&lt;6)</span></p><p><span style="font-family:宋体;font-size:14px;">#define KAUTH_VNODE_READ_ATTRIBUTES             (1&lt;&lt;7)</span></p><p><span style="font-family:宋体;font-size:14px;">#define KAUTH_VNODE_WRITE_ATTRIBUTES            (1&lt;&lt;8)</span></p><p><span style="font-family:宋体;font-size:14px;">#define KAUTH_VNODE_READ_EXTATTRIBUTES          (1&lt;&lt;9)</span></p><p><span style="font-family:宋体;font-size:14px;">#define KAUTH_VNODE_WRITE_EXTATTRIBUTES         (1&lt;&lt;10)</span></p><p><span style="font-family:宋体;font-size:14px;">#define KAUTH_VNODE_READ_SECURITY               (1&lt;&lt;11)</span></p><p><span style="font-family:宋体;font-size:14px;">#define KAUTH_VNODE_WRITE_SECURITY              (1&lt;&lt;12)</span></p><p><span style="font-family:宋体;font-size:14px;">#define KAUTH_VNODE_TAKE_OWNERSHIP              (1&lt;&lt;13)</span></p><p><span style="font-family:宋体;font-size:14px;">#define KAUTH_VNODE_SYNCHRONIZE                 (1&lt;&lt;20)</span></p><p><span style="font-family:宋体;font-size:14px;">#define KAUTH_VNODE_LINKTARGET                  (1&lt;&lt;25)</span></p><p><span style="font-family:宋体;font-size:14px;">#define KAUTH_VNODE_CHECKIMMUTABLE              (1&lt;&lt;26)</span></p><p><span style="font-family:宋体;font-size:14px;">#define KAUTH_VNODE_ACCESS                      (1&lt;&lt;31)</span></p><p><span style="font-family:宋体;font-size:14px;">#define KAUTH_VNODE_NOIMMUTABLE                 (1&lt;&lt;30)</span></p><p><span style="font-family:宋体;font-size:14px;">#define KAUTH_VNODE_SEARCHBYANYONE              (1&lt;&lt;29)</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">为了加快检查速度，</span>xnu<span style="font-family:宋体;">使用了一个</span><span style="font-family:Calibri;">cache</span><span style="font-family:宋体;">机制，在</span><span style="font-family:Calibri;">vnode</span><span style="font-family:宋体;">的结构体加入了</span><span style="font-family:Calibri;">v_authorized_actions</span><span style="font-family:宋体;">成员，它代表了上一次是做的哪项权限检查，通过调用</span><span style="font-family:Calibri;">vnode_cache_is_authorized</span><span style="font-family:宋体;">执行</span><span style="font-family:Calibri;">vp-&gt;v_authorized_actions &amp; action</span><span style="font-family:宋体;">，来判断是否命中上次</span><span style="font-family:Calibri;">cache</span><span style="font-family:宋体;">，之后在执行完权限检查后，通过调用</span><span style="font-family:Calibri;">vnode_cache_authorized_action</span><span style="font-family:宋体;">执行</span><span style="font-family:Calibri;">vp-&gt;v_authorized_actions |= action</span><span style="font-family:宋体;">更新</span><span style="font-family:Calibri;">cache</span><span style="font-family:宋体;">。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">Xnu<span style="font-family:宋体;">将文件系统的</span><span style="font-family:Calibri;">acl</span><span style="font-family:宋体;">评估机制也封装到了</span><span style="font-family:Calibri;">kauth</span><span style="font-family:宋体;">子系统里。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">bsd/sys/kauth.h</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">kauth_acl</span> {</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">u_int32_t</span>       acl_entrycount;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">u_int32_t</span>       acl_flags;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">kauth_ace</span> <span class="code-snippet__title">acl_ace</span>[1];</span></span></code><code><span class="code-snippet_outer">};</span></code></pre></section><p><span style="font-family:Calibri;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;">acl_entrycount</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">表示的是</span></span><span style="font-family:Calibri;font-size:14px;">struct kauth_ace acl_ace</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">数组的大小。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">kauth_ace</span> {</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">guid_t</span>          ace_applicable;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">u_int32_t</span>       ace_flags;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">kauth_ace_rights_t</span> ace_rights;          </span></code><code><span class="code-snippet_outer">};</span></code></pre></section><p><span style="font-family:Calibri;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">一个</span>acl entry<span style="font-family:宋体;">定义为</span><span style="font-family:Calibri;">struct kauth_ace</span><span style="font-family:宋体;">结构，</span><span style="font-family:Calibri;">acl</span><span style="font-family:宋体;">评估的业界通用算法就是从前到后，依次对比每个</span><span style="font-family:Calibri;">ace</span><span style="font-family:宋体;">项，如果权限匹配为</span><span style="font-family:Calibri;">deny</span><span style="font-family:宋体;">，则直接返回失败，否则进行下一个</span><span style="font-family:Calibri;">ace</span><span style="font-family:宋体;">匹配。</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">在函数</span>vnode_authorize_simple<span style="font-family:宋体;">里判断</span><span style="font-family:Calibri;">vnode</span><span style="font-family:宋体;">结构的</span><span style="font-family:Calibri;">acl</span><span style="font-family:宋体;">链表是否为空，如果不为空则调用</span><span style="font-family:Calibri;">kauth_acl_evaluate</span><span style="font-family:宋体;">进行</span><span style="font-family:Calibri;">acl</span><span style="font-family:宋体;">权限检查。</span></span></p>



<p><a href="2247483720">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=4527ea2a&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg4NjU1NDU4MA%3D%3D%26mid%3D2247483720%26idx%3D1%26sn%3Dc96728b68781eef0e3d1e7fa68a9683f%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Thu, 28 Jan 2021 11:32:00 +0800</pubDate>
    </item>
    <item>
      <title>XNU内核堆安全特性解读</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg4NjU1NDU4MA==&amp;mid=2247483715&amp;idx=1&amp;sn=09f81eaff411d8297a5937912901af5b</link>
      <description>XNU zone内存分配器安全特性解读</description>
      <content:encoded><![CDATA[<p>
原创 <span>wzt</span> <span>2021-01-14 16:39</span> <span style="display: inline-block;"></span>
</p>

<p>XNU zone内存分配器安全特性解读</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=d3faff88&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F4iaJia7Cvd3PD8mE3daWIrnZx88WM3y5aYp1eJp4k41hwiaJBE7Xvnjqhia2re6fb5wvIICuC3IiaMf6TLW8DeS2ib2Q%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<h2 style="margin-left:0;text-indent:0;"><span style="font-family:Arial;font-weight:bold;font-size:21px;">1.1 </span><strong><span style="font-family: 黑体;font-size: 21px;"><span style="font-family:黑体;">简介</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">XNU<span style="font-family:宋体;">的内核内存分配器层次比较多， 因为它是一个混合的内核，</span><span style="font-family:Calibri;">bsd</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">mach</span><span style="font-family:宋体;">层都有自己的内存分配器接口， 但最底层的都是调用</span><span style="font-family:Calibri;">zone allocotr</span><span style="font-family:宋体;">分配器。它的内存分配器设计非常简单，大概是我读过的众多主流</span><span style="font-family:Calibri;">os</span><span style="font-family:宋体;">内核中无论数据结构还是分配算法都是最简单的一个。我时常在想</span><span style="font-family:Calibri;">XNU</span><span style="font-family:宋体;">内核给</span><span style="font-family:Calibri;">MacOS</span><span style="font-family:宋体;">提供了流畅的操作性，但是只从</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">的内存分配器来看并不能支撑这个结论，或许慢慢随着笔者对</span><span style="font-family:Calibri;">XNU</span><span style="font-family:宋体;">内核的深入理解，答案也会慢慢水落石出。不过本次我们将探讨下</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">内存分配器的安全特性以及设计不足，值得肯定的是</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">内存分配器在调试和安全特性上的支持已经远远甩出了</span><span style="font-family:Calibri;">FREEBSD</span><span style="font-family:宋体;">内核，于</span><span style="font-family:Calibri;">linux</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">slab</span><span style="font-family:宋体;">内存分配器也有过之而无不及， 各有春秋。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h2 style="margin-left:0;text-indent:0;"><span style="font-family:Arial;font-weight:bold;font-size:21px;">1.2 </span><strong><span style="font-family: 黑体;font-size: 21px;">zone<span style="font-family:黑体;">分配器的基本结构</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">Zone<span style="font-family:宋体;">分配器的最基本管理结构为</span><span style="font-family:Calibri;">struct zone_page_metadata</span><span style="font-family:宋体;">， 它相当于</span><span style="font-family:Calibri;">linux slab</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">slab</span><span style="font-family:宋体;">管理结构体。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">zone_page_metadata</span> {</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">queue_chain_t</span>           pages;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">union</span> {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">uint32_t</span>                freelist_offset;</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">uint32_t</span>                real_metadata_offset;</span></code><code><span class="code-snippet_outer">        };</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">uint16_t</span>                        free_count;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsigned</span>                        zindex     : ZINDEX_BITS;   </span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsigned</span>                        page_count : PAGECOUNT_BITS;</span></code><code><span class="code-snippet_outer">};</span></code></pre></section><p><span style="font-family:Calibri;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">结构成员中最重要的是</span></span><span style="font-family:Calibri;font-size:14px;">freelist_offset</span><span style="font-family:宋体;font-size:14px;">, <span style="font-family:宋体;">它保存的是下一个空闲的</span><span style="font-family:Calibri;">item</span><span style="font-family:宋体;">地址。 一个</span><span style="font-family:Calibri;">item</span><span style="font-family:宋体;">在内存中的结构图为：</span></span></p><p><span style="font-family:宋体;font-size:14px;">----------------------------------------------------------------------------------</span></p><p><span style="font-family:宋体;font-size:14px;">|redzone|redzone|...| next pointer| posion| posion|...| backup pointer|redzone|redzone|</span></p><p><span style="font-family:宋体;font-size:14px;">----------------------------------------------------------------------------------</span></p><h2><br/></h2><h2><strong><span style="font-family: 黑体;font-size: 21px;">1.3 <span style="font-family:黑体;">堆溢出检测</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">业界常用的检测堆溢出的算法为在一个</span>item<span style="font-family:宋体;">前后填充若干</span><span style="font-family:Calibri;">redzone</span><span style="font-family:宋体;">值，申请或释放内存时对</span><span style="font-family:Calibri;">redzone</span><span style="font-family:宋体;">值进行检测，以发现是否有溢出行为的发生。</span><span style="font-family:Calibri;">XNU</span><span style="font-family:宋体;">内核只有在打开</span><span style="font-family:Calibri;">KASAN_ZALLOC</span><span style="font-family:宋体;">内核选项时才会填充</span><span style="font-family:Calibri;">redzone</span><span style="font-family:宋体;">。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">osfmk/kern/zalloc.c：</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">inline</span> vm_offset_t</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">try_alloc_from_zone</span><span class="code-snippet__params">(<span class="code-snippet__keyword">zone_t</span> zone,</span></span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">vm_tag_t</span> tag __unused,</span></code><code><span class="code-snippet_outer">                    <span class="code-snippet__keyword">boolean_t</span>* check_poison)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">if</span> KASAN_ZALLOC</span></span></code><code><span class="code-snippet_outer">        kasan_poison_range(element, zone-&gt;elem_size, ASAN_VALID);</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">endif</span></span></span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">kasan_poison_range-&gt;<span class="code-snippet__function">kasan_poison</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">kasan_poison</span><span class="code-snippet__params">(<span class="code-snippet__keyword">vm_offset_t</span> base, <span class="code-snippet__keyword">vm_size_t</span> size, <span class="code-snippet__keyword">vm_size_t</span> leftrz, <span class="code-snippet__keyword">vm_size_t</span> rightrz, <span class="code-snippet__keyword">uint8_t</span> flags)</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">uint8_t</span> *shadow = SHADOW_FOR_ADDRESS(base);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">uint8_t</span> partial = size &amp; <span class="code-snippet__number">0x07</span>;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">vm_size_t</span> total = leftrz + size + rightrz;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">vm_size_t</span> i = <span class="code-snippet__number">0</span>; </span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (!kasan_enabled || !kasan_poison_active(flags)) {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">return</span>;</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        leftrz /= <span class="code-snippet__number">8</span>;</span></code><code><span class="code-snippet_outer">        size /= <span class="code-snippet__number">8</span>;</span></code><code><span class="code-snippet_outer">        total /= <span class="code-snippet__number">8</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">uint8_t</span> l_flags = flags;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">uint8_t</span> r_flags = flags;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (flags == ASAN_STACK_RZ) {</span></code><code><span class="code-snippet_outer">                l_flags = ASAN_STACK_LEFT_RZ;</span></code><code><span class="code-snippet_outer">                r_flags = ASAN_STACK_RIGHT_RZ;</span></code><code><span class="code-snippet_outer">        } <span class="code-snippet__keyword">else</span> <span class="code-snippet__keyword">if</span> (flags == ASAN_HEAP_RZ) {</span></code><code><span class="code-snippet_outer">                l_flags = ASAN_HEAP_LEFT_RZ;</span></code><code><span class="code-snippet_outer">                r_flags = ASAN_HEAP_RIGHT_RZ;</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">for</span> (; i &lt; leftrz; i++) {</span></code><code><span class="code-snippet_outer">                shadow[i] = l_flags;</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">for</span> (; i &lt; leftrz + size; i++) {</span></code><code><span class="code-snippet_outer">                shadow[i] = ASAN_VALID; <span class="code-snippet__comment">/* <span class="code-snippet__doctag">XXX:</span> should not be necessary */</span></span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (partial &amp;&amp; (i &lt; total)) {</span></code><code><span class="code-snippet_outer">                shadow[i] = partial;</span></code><code><span class="code-snippet_outer">                i++;</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">for</span> (; i &lt; total; i++) {</span></code><code><span class="code-snippet_outer">                shadow[i] = r_flags;</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:Calibri;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">Zone<span style="font-family:宋体;">依据内存分配器的不同阶段，调用</span></span><span style="font-family:Calibri;font-size:14px;">kasan_poison</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">时构造的</span>item<span style="font-family:宋体;">前后</span><span style="font-family:Calibri;">redzone</span><span style="font-family:宋体;">填充值也不相同。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer">san/kasan.h</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">define</span> ASAN_VALID          0x00</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">define</span> ASAN_HEAP_RZ        0xe9</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">define</span> ASAN_HEAP_LEFT_RZ   0xfa</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">define</span> ASAN_HEAP_RIGHT_RZ  0xfb</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">define</span> ASAN_HEAP_FREED     0xfd</span></span></code></pre></section><p><span style="font-family:Calibri;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">Redzone<span style="font-family:宋体;">的填充值与其他</span><span style="font-family:Calibri;">OS</span><span style="font-family:宋体;">的实现一样都使用了默认值， </span><span style="font-family:Calibri;">exploit</span><span style="font-family:宋体;">程序很容易对其绕过，在笔者给</span><span style="font-family:Calibri;">linux slab</span><span style="font-family:宋体;">开发的内核加固补丁</span><span style="font-family:Calibri;">AKSP</span><span style="font-family:宋体;">中，堆</span><span style="font-family:Calibri;">redzone</span><span style="font-family:宋体;">使用了随机值，进一步提升了安全性。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h2><strong><span style="font-family: 黑体;font-size: 21px;">1.4 DOUBLE FREE<span style="font-family:黑体;">检测</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">Zone<span style="font-family:宋体;">内存分配器可以做简单的</span><span style="font-family:Calibri;">double free</span><span style="font-family:宋体;">检测。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">osfmk/kern/zalloc.c：</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">inline</span> <span class="code-snippet__keyword">void</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">free_to_zone</span><span class="code-snippet__params">(<span class="code-snippet__keyword">zone_t</span>      zone,</span></span></code><code><span class="code-snippet_outer">             <span class="code-snippet__keyword">vm_offset_t</span> element,</span></code><code><span class="code-snippet_outer">             <span class="code-snippet__keyword">boolean_t</span>   poison)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">page_meta = get_zone_page_metadata((struct zone_free_element *)element, FALSE); [<span class="code-snippet__number">1</span>]</span></code><code><span class="code-snippet_outer">    old_head = (<span class="code-snippet__keyword">vm_offset_t</span>)page_metadata_get_freelist(page_meta);              [<span class="code-snippet__number">2</span>]</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span> (__improbable(old_head == element))                 [<span class="code-snippet__number">3</span>]</span></code><code><span class="code-snippet_outer">         panic(<span class="code-snippet__string">&#34;zfree: double free of %p to zone %s\n&#34;</span>,</span></code><code><span class="code-snippet_outer">              (<span class="code-snippet__keyword">void</span> *) element, zone-&gt;zone_name);</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:宋体;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">[1] </span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">处通过参数</span>element<span style="font-family:宋体;">获取</span><span style="font-family:Calibri;">struct zone_page_metadata</span><span style="font-family:宋体;">管理体地址，然后获取其保存的下一个空闲</span><span style="font-family:Calibri;">item</span><span style="font-family:宋体;">地址</span><span style="font-family:Calibri;">old_head, </span><span style="font-family:宋体;">在</span><span style="font-family:Calibri;">[3]</span><span style="font-family:宋体;">进行比对， 如果相等说明有重复释放的行为。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">这种算法只能检测简单的</span>double free<span style="font-family:宋体;">操作，也就是连续释放两次相同的</span><span style="font-family:Calibri;">item</span><span style="font-family:宋体;">地址。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">Free(addr1);</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">Free(addr1);</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">对于下面这种情况就检测不到了。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">Free(addr1);</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">Free(addr2);</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">Free(addr1);</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">在笔者给</span>linux slab<span style="font-family:宋体;">开发的内核加固补丁</span><span style="font-family:Calibri;">AKSP</span><span style="font-family:宋体;">中，可以检测上述或者更复杂的多重释放问题。</span></span></p><p><span style="font-family:宋体;font-size:14px;"> </span></p><h2><strong><span style="font-family: 黑体;font-size: 21px;">1.5 UAF<span style="font-family:黑体;">检测</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">业界常用的</span>UFA<span style="font-family:宋体;">检测算法是给</span><span style="font-family:Calibri;">item</span><span style="font-family:宋体;">填充固定的</span><span style="font-family:Calibri;">poison</span><span style="font-family:宋体;">值，在申请内存时检测</span><span style="font-family:Calibri;">posion</span><span style="font-family:宋体;">是否改变以此来发现</span><span style="font-family:Calibri;">UAF</span><span style="font-family:宋体;">的行为。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">osfmk/kern/zalloc.<span class="code-snippet__function">c</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span> *</span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">zalloc_internal</span><span class="code-snippet__params">(</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">zone_t</span>  zone,</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">boolean_t</span> canblock,</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">boolean_t</span> nopagewait,</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">vm_size_t</span></span></code><code><span class="code-snippet_outer">#<span class="code-snippet__keyword">if</span> !VM_MAX_TAG_ZONES</span></code><code><span class="code-snippet_outer">    __unused</span></code><code><span class="code-snippet_outer">#endif</span></code><code><span class="code-snippet_outer">    reqsize,</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">vm_tag_t</span>  tag)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        zalloc_poison_element(check_poison, zone, addr);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">void</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">zalloc_poison_element</span><span class="code-snippet__params">(<span class="code-snippet__keyword">boolean_t</span> check_poison, <span class="code-snippet__keyword">zone_t</span> zone, <span class="code-snippet__keyword">vm_offset_t</span> addr)</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">vm_offset_t</span>     inner_size = zone-&gt;elem_size;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (__improbable(check_poison &amp;&amp; addr)) {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">vm_offset_t</span> *element_cursor  = ((<span class="code-snippet__keyword">vm_offset_t</span> *) addr) + <span class="code-snippet__number">1</span>;       [<span class="code-snippet__number">1</span>]</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">vm_offset_t</span> *backup  = get_backup_ptr(inner_size, (<span class="code-snippet__keyword">vm_offset_t</span> *) addr);[<span class="code-snippet__number">2</span>]</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">for</span> ( ; element_cursor &lt; backup ; element_cursor++)[<span class="code-snippet__number">3</span>]</span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">if</span> (__improbable(*element_cursor != ZP_POISON))</span></code><code><span class="code-snippet_outer">                                zone_element_was_modified_panic(zone,</span></code><code><span class="code-snippet_outer">                                                                addr,</span></code><code><span class="code-snippet_outer">                                                                *element_cursor,</span></code><code><span class="code-snippet_outer">                                                                ZP_POISON,</span></code><code><span class="code-snippet_outer">                                                                ((<span class="code-snippet__keyword">vm_offset_t</span>)element_cursor) - addr);</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:宋体;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">[1] </span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">处首先取得</span>poison<span style="font-family:宋体;">的首地址，注意</span><span style="font-family:Calibri;">item</span><span style="font-family:宋体;">的第一个地址为加密后的</span><span style="font-family:Calibri;">next pointer</span><span style="font-family:宋体;">值，它是与</span><span style="font-family:Calibri;">zp_nopoison_cookie</span><span style="font-family:宋体;">异或计算的结果，所以要跳过第一个地址， </span><span style="font-family:Calibri;">[2]</span><span style="font-family:宋体;">处取得</span><span style="font-family:Calibri;">posion</span><span style="font-family:宋体;">的最后一个地址，在前面的</span><span style="font-family:Calibri;">item</span><span style="font-family:宋体;">内存结构视图中可以看到</span><span style="font-family:Calibri;">item</span><span style="font-family:宋体;">的最后一个地址保存的是</span><span style="font-family:Calibri;">next_pointer</span><span style="font-family:宋体;">的值，它是与</span><span style="font-family:Calibri;">zp_poisoned_cookie</span><span style="font-family:宋体;">或者</span><span style="font-family:Calibri;">zp_nopoison_cookie</span><span style="font-family:宋体;">异或计算的结果。</span></span></p><p><span style="font-family:宋体;font-size:14px;">zp_poisoned_cookie<span style="font-family:宋体;">与</span><span style="font-family:Calibri;">zp_nopoison_cookie</span><span style="font-family:宋体;">是在</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">子系统初始化时动态随机生成的，所有的</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">共用同一个值。</span><span style="font-family:Calibri;">[3]</span><span style="font-family:宋体;">处与默认填充的</span><span style="font-family:Calibri;">poison</span><span style="font-family:宋体;">值进行比对</span><span style="font-family:Calibri;">, </span><span style="font-family:宋体;">如果比对失败，说明这个</span><span style="font-family:Calibri;">item</span><span style="font-family:宋体;">在分配之前已经被改写过了。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">前面分析过</span>item<span style="font-family:宋体;">的第一个地址保存的是</span><span style="font-family:Calibri;">next pointer</span><span style="font-family:宋体;">的一个混淆值， 在</span><span style="font-family:Calibri;">item</span><span style="font-family:宋体;">的最后还保存了一个</span><span style="font-family:Calibri;">next pointer</span><span style="font-family:宋体;">的混淆值副本。所以除了填充</span><span style="font-family:Calibri;">poison</span><span style="font-family:宋体;">的方法， </span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">内存分配器还可以使用</span><span style="font-family:Calibri;">next pointer</span><span style="font-family:宋体;">和其副本的对比，来发现</span><span style="font-family:Calibri;">UAF</span><span style="font-family:宋体;">的行为。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">inline</span> vm_offset_t</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">try_alloc_from_zone</span><span class="code-snippet__params">(<span class="code-snippet__keyword">zone_t</span> zone,</span></span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">vm_tag_t</span> tag __unused,</span></code><code><span class="code-snippet_outer">                    <span class="code-snippet__keyword">boolean_t</span>* check_poison)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (__improbable(next_element != (next_element_backup ^ zp_nopoison_cookie))) {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> (__improbable(next_element != (next_element_backup ^ zp_poisoned_cookie)))</span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__comment">/* Neither cookie is valid, corruption has occurred */</span></span></code><code><span class="code-snippet_outer">                        backup_ptr_mismatch_panic(zone, element, next_element_primary, next_element_backup);</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:宋体;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">由于</span>next pointer<span style="font-family:宋体;">的副本根据是否需要填充</span><span style="font-family:Calibri;">poison</span><span style="font-family:宋体;">使用不同的</span><span style="font-family:Calibri;">xor</span><span style="font-family:宋体;">值，所以分别进行了两次比对。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">在进行完</span>UAF<span style="font-family:宋体;">检查后，</span><span style="font-family:Calibri;">zalloc_poison_element</span><span style="font-family:宋体;">还会堆</span><span style="font-family:Calibri;">next pointer</span><span style="font-family:宋体;">进行擦除，以后防止地址泄露，并且从泄露的地址推测</span></span><span style="font-family:Calibri;font-size:14px;">zp_nopoison_cookie</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">随机值。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">void</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__title">zalloc_poison_element</span><span class="code-snippet__params">(<span class="code-snippet__keyword">boolean_t</span> check_poison, <span class="code-snippet__keyword">zone_t</span> zone, <span class="code-snippet__keyword">vm_offset_t</span> addr)</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (addr) {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">vm_offset_t</span> *primary  = (<span class="code-snippet__keyword">vm_offset_t</span> *) addr;</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">vm_offset_t</span> *backup   = get_backup_ptr(inner_size, primary);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">                *primary = ZP_POISON;</span></code><code><span class="code-snippet_outer">                *backup  = ZP_POISON;</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><br/></p><p><span style="font-family:宋体;font-size:14px;"></span></p><h2><strong><span style="font-family: 黑体;font-size: 21px;">1.6 item<span style="font-family:黑体;">地址随机化</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">内核堆的攻击技术链中，</span>item<span style="font-family:宋体;">的地址初始化顺序十分重要， </span><span style="font-family:Calibri;">exploit</span><span style="font-family:宋体;">以此来精确控制要覆盖的</span><span style="font-family:Calibri;">item</span><span style="font-family:宋体;">地址， </span><span style="font-family:Calibri;">linux slab</span><span style="font-family:宋体;">使用了洗牌算法将</span><span style="font-family:Calibri;">slab</span><span style="font-family:宋体;">里</span><span style="font-family:Calibri;">item</span><span style="font-family:宋体;">的初始化顺序完全打乱。但是</span><span style="font-family:Calibri;">XNU</span><span style="font-family:宋体;">内核使用的</span><span style="font-family:Calibri;">item</span><span style="font-family:宋体;">随机化只有两种情况， 正向顺序或逆向顺序，这只能在一定程度上缓解地址随机化问题，相比</span><span style="font-family:Calibri;">linux</span><span style="font-family:宋体;">的洗牌算法会变弱了很多。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="properties"><code><span class="code-snippet_outer"><span class="code-snippet__attr">random_free_to_zone(</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">                        zone_t          zone,</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">                        vm_offset_t     newmem,</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">                        vm_offset_t     first_element_offset,</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">                        int             element_count,</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">                        unsigned int    *entropy_buffer)</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">{</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__meta">assert(element_count</span> <span class="code-snippet__string">&amp;&amp; element_count &lt;= ZONE_CHUNK_MAXELEMENTS);</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">        elem_size </span>=<span class="code-snippet__string"> zone-&gt;elem_size;</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">        last_element_offset </span>=<span class="code-snippet__string"> first_element_offset + ((element_count * elem_size) - elem_size);</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">        for (index </span>=<span class="code-snippet__string"> 0; index &lt; element_count; index++) {</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">                assert(first_element_offset &lt;</span>=<span class="code-snippet__string"> last_element_offset);</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">                if (</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">#if DEBUG || DEVELOPMENT</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">                leak_scan_debug_flag || __improbable(zone-&gt;tags) ||</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">#endif /* DEBUG || DEVELOPMENT */</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">                random_bool_gen_bits(&amp;zone_bool_gen, entropy_buffer, MAX_ENTROPY_PER_ZCRAM, 1)) {[1]</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">                        element_addr </span>=<span class="code-snippet__string"> newmem + first_element_offset;</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">                        first_element_offset +</span>=<span class="code-snippet__string"> elem_size;</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">                } else {[2]</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">                        element_addr </span>=<span class="code-snippet__string"> newmem + last_element_offset;</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">                        last_element_offset -</span>=<span class="code-snippet__string"> elem_size;</span></span></code><code><span class="code-snippet_outer">                <span class="code-snippet__attr">}</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">                if (element_addr !</span>=<span class="code-snippet__string"> (vm_offset_t)zone) {</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">                        zone-&gt;count++;  /* compensate for free_to_zone */</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">                        free_to_zone(zone, element_addr, FALSE);</span></span></code><code><span class="code-snippet_outer">                <span class="code-snippet__attr">}</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">                zone-&gt;cur_size +</span>=<span class="code-snippet__string"> elem_size;</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__attr">}</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">}</span></span></code></pre></section><p><span style="font-family:Calibri;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;">random_bool_gen_bits</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">产生一些随机的</span>0<span style="font-family:宋体;">或</span><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">，从而选择是正向顺序分配还是逆向顺序分配</span><span style="font-family:Calibri;">item</span><span style="font-family:宋体;">地址。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h2><strong><span style="font-family: 黑体;font-size: 21px;">1.7 <span style="font-family:黑体;">内存拷贝检查</span></span></strong></h2><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">Zone<span style="font-family:宋体;">内存分配器提供了一个启动参数</span><span style="font-family:Calibri;">-no-copyio-zalloc-check, </span><span style="font-family:宋体;">当发生从用户空间向内核空间拷贝数据时，会检测内核空间是否属于</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">的空间，如果属于那么拷贝的字节数就不能大于</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">item size</span><span style="font-family:宋体;">，这是一个非常棒的安全检测功能。有点类似</span><span style="font-family:Calibri;">linux slab</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">hardened user copy</span><span style="font-family:宋体;">算法， 只不过它防止的是从内核向用户空间拷贝敏感的数据，限制了拷贝的范围。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h2><strong><span style="font-family: 黑体;font-size: 21px;">1.8 <span style="font-family:黑体;">双向安全链表</span></span></strong></h2><p style="text-indent: 28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">尽管针对内核堆溢出的攻击中，</span> <span style="font-family:宋体;">很少见到改写双向链表节点的攻击手段。但是为了防患于未然，或者说养成良好的安全编程习惯，</span> NT<span style="font-family:宋体;">和</span><span style="font-family:Calibri;">linux</span><span style="font-family:宋体;">内核都使用了安全双向链表检查，而</span><span style="font-family:Calibri;">XNU</span><span style="font-family:宋体;">未提供此能力。</span></span></p>



<p><a href="2247483715">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=5238b2b8&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg4NjU1NDU4MA%3D%3D%26mid%3D2247483715%26idx%3D1%26sn%3D09f81eaff411d8297a5937912901af5b%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Thu, 14 Jan 2021 16:39:00 +0800</pubDate>
    </item>
    <item>
      <title>Freebsd UMA内核堆安全特性解读</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg4NjU1NDU4MA==&amp;mid=2247483710&amp;idx=1&amp;sn=b91c0b55bb96ad5f3690ab64fca43780</link>
      <description>freebsd内核内存分配器安全特性分析</description>
      <content:encoded><![CDATA[<p>
原创 <span>wzt</span> <span>2021-01-11 17:52</span> <span style="display: inline-block;"></span>
</p>

<p>freebsd内核内存分配器安全特性分析</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=772e33d6&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F4iaJia7Cvd3PCE9Lej5jz05DHm4S69YQUyibibFmUdZCU5ON18hMJqrxwrvR1eHHQqdHrwTm3fnu9j2JWK6W23kdvQ%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<h3 style="margin-left:0;text-indent:0;"><span style="font-family:Calibri;font-weight:bold;font-size:21px;">1.1 </span><strong><span style="font-family: 宋体;font-size: 21px;"><span style="font-family:宋体;">简介</span></span></strong></h3><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">Freebsd<span style="font-family:宋体;">的内核内存分配器叫做</span><span style="font-family:Calibri;">UMA(Universal Memory Allocator)</span><span style="font-family:宋体;">，这篇文章只关心它的安全特性，对于常规功能实现请读者朋友参考网络上的其他文章。它的安全功能特性相比</span><span style="font-family:Calibri;">XNU</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">NT</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">LINUX</span><span style="font-family:宋体;">都少了很多，并且还存在一些不安全的构架设计，下面将会详细分析。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h3 style="margin-left:0;text-indent:0;"><span style="font-family:Calibri;font-weight:bold;font-size:21px;">1.2 </span><strong><span style="font-family: 宋体;font-size: 21px;"><span style="font-family:宋体;">架构设计缺点</span></span></strong></h3><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">UMA<span style="font-family:宋体;">的总体架构也是基于</span><span style="font-family:Calibri;">solaris slab</span><span style="font-family:宋体;">， 我们直接看最底层的</span><span style="font-family:Calibri;">slab</span><span style="font-family:宋体;">结构，一个</span><span style="font-family:Calibri;">slab</span><span style="font-family:宋体;">大小为</span><span style="font-family:Calibri;">PAGE_SIZE</span><span style="font-family:宋体;">，</span><span style="font-family:Calibri;">slab</span><span style="font-family:宋体;">的管理体结构依据</span><span style="font-family:Calibri;">slab</span><span style="font-family:宋体;">里的每个</span><span style="font-family:Calibri;">item</span><span style="font-family:宋体;">大小而决定，对于小块</span><span style="font-family:Calibri;">item</span><span style="font-family:宋体;">，</span><span style="font-family:Calibri;">slab</span><span style="font-family:宋体;">管理结构体放在</span><span style="font-family:Calibri;">slab</span><span style="font-family:宋体;">里，并且是放到</span><span style="font-family:Calibri;">PAGE_SIZE</span><span style="font-family:宋体;">的最后。对于大块</span><span style="font-family:Calibri;">item</span><span style="font-family:宋体;">，管理结构体则单独分配一个内存，不包含在</span><span style="font-family:Calibri;">slab</span><span style="font-family:宋体;">里。</span></span></p><p><strong><span style="font-family: Calibri;font-size: 14px;">       &lt;---------------Page (UMA_SLAB_SIZE) ----------&gt;</span></strong></p><p><strong><span style="font-family: Calibri;font-size: 14px;">       __________________________________________</span></strong></p><p><strong><span style="font-family: Calibri;font-size: 14px;">      | _  _  _  _  _  _  _  _  _  _  _  _  _  _  _   ___________ |</span></strong></p><p><strong><span style="font-family: Calibri;font-size: 14px;">      ||i||i||i||i||i||i||i||i||i||i||i||i| |slab header||</span></strong></p><p><strong><span style="font-family: Calibri;font-size: 14px;">      ||_||_||_||_||_||_||_||_||_||_||_||_||_||_||</span></strong></p><p><strong><span style="font-family: Calibri;font-size: 14px;">      |_________________________________________|</span></strong></p><p><strong><span style="font-family: Calibri;font-size: 14px;"> </span></strong></p><p><strong><span style="font-family: Calibri;font-size: 14px;">       This is an OFFPAGE slab. These can be larger than UMA_SLAB_SIZE.</span></strong></p><p><strong><span style="font-family: Calibri;font-size: 14px;">       ______________________________________</span></strong></p><p><strong><span style="font-family: Calibri;font-size: 14px;">      | _  _  _  _  _  _  _  _  _  _  _  _  _  _  _  _  _  _  _   |</span></strong></p><p><strong><span style="font-family: Calibri;font-size: 14px;">      ||i||i||i||i||i||i||i||i||i||i||i||i||i||i||i|  |</span></strong></p><p><strong><span style="font-family: Calibri;font-size: 14px;">      ||_||_||_||_||_||_||_||_||_||_||_||_||_||</span></strong></p><p><strong><span style="font-family: Calibri;font-size: 14px;">      |_____________________________________-|</span></strong></p><p><strong><span style="font-family: Calibri;font-size: 14px;">        ___________    ^</span></strong></p><p><strong><span style="font-family: Calibri;font-size: 14px;">       |slab header|   |</span></strong></p><p><strong><span style="font-family: Calibri;font-size: 14px;">       |___________|---*</span></strong></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"> </span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">对于小块</span>item<span style="font-family:宋体;">， </span><span style="font-family:Calibri;">slab</span><span style="font-family:宋体;">这种设计属于严重的安全错误设计，</span><span style="font-family:Calibri;">slab header</span><span style="font-family:宋体;">放在所有</span><span style="font-family:Calibri;">item</span><span style="font-family:宋体;">的最后，如果最后一个</span><span style="font-family:Calibri;">item</span><span style="font-family:宋体;">发生溢出，就可以直接覆盖</span><span style="font-family:Calibri;">slab header</span><span style="font-family:宋体;">里的数据结构。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">uma_slab</span> {</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">uma_keg_t</span>       us_keg;                 <span class="code-snippet__comment">/* Keg we live in */</span></span></code><code><span class="code-snippet_outer">...</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:宋体;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">Slab header<span style="font-family:宋体;">结构为</span><span style="font-family:Calibri;">struct Uma_slab</span><span style="font-family:宋体;">，它的第一个成员是</span><span style="font-family:Calibri;">us_keg</span><span style="font-family:宋体;">。</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">uma_keg</span> {</span></span></code><code><span class="code-snippet_outer"> LIST_HEAD(,uma_zone)    uk_zones;       <span class="code-snippet__comment">/* Keg&#39;s zones */</span></span></code><code><span class="code-snippet_outer">...</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:宋体;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">Uk_zones<span style="font-family:宋体;">结构为：</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">uma_zone</span> {</span></span></code><code><span class="code-snippet_outer">        uma_ctor        uz_ctor;        <span class="code-snippet__comment">/* Constructor for each allocation */</span></span></code><code><span class="code-snippet_outer">        uma_dtor        uz_dtor;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:宋体;font-size:14px;"></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">结构体成员</span>uz_ctor<span style="font-family:宋体;">和</span><span style="font-family:Calibri;">uz_dtor</span><span style="font-family:宋体;">为每个</span><span style="font-family:Calibri;">zone</span><span style="font-family:宋体;">在创建和销毁时调用的析构函数指针，</span><span style="font-family:Calibri;">exploit</span><span style="font-family:宋体;">程序一般都会替换这两个函数指针，使其指向</span><span style="font-family:Calibri;">shellcode</span><span style="font-family:宋体;">地址。</span><span style="font-family:Calibri;">Slab header</span><span style="font-family:宋体;">放在最后，使堆溢出攻击相对</span><span style="font-family:Calibri;">linux</span><span style="font-family:宋体;">变得更加简单， 因为</span><span style="font-family:Calibri;">linux</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">slab header</span><span style="font-family:宋体;">就是放在最前面的。我们在设计内存分配器时就要避免这个糟糕的设计，同时管理结构体中函数指针的定义一定要做到最少，防止被</span><span style="font-family:Calibri;">exploit</span><span style="font-family:宋体;">程序滥用。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h3 style="margin-left:0;text-indent:0;"><span style="font-family:Calibri;font-weight:bold;font-size:21px;">1.3 </span><strong><span style="font-family: 宋体;font-size: 21px;"><span style="font-family:宋体;">安全特性缺失</span></span></strong></h3><h4><strong><span style="font-family: 黑体;font-size: 19px;">1.3.1 <span style="font-family:黑体;">溢出检测</span></span></strong></h4><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">能检测到溢出情况的发生是每个内存分配器的基础安全能力，业界的通用算法是在内存区块的前后加入</span>redzone<span style="font-family:宋体;">，在初始化时填充一个固定值，在内存释放时检测</span><span style="font-family:Calibri;">redzone</span><span style="font-family:宋体;">里的固定值是否有改变来判断是否有溢出行为的发生。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">UMA<span style="font-family:宋体;">的</span><span style="font-family:Calibri;">redzone</span><span style="font-family:宋体;">结构为：</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">-----------------------------------------------------------------------------</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">| struct stack | size |0x42|0x42|...|    data       |0x42|0x42|...|</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">-----------------------------------------------------------------------------</span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">在</span>data<span style="font-family:宋体;">的前面分别为</span><span style="font-family:Calibri;">struct stack </span><span style="font-family:宋体;">保存的是当前栈信息，</span><span style="font-family:Calibri;">size</span><span style="font-family:宋体;">为</span><span style="font-family:Calibri;">data</span><span style="font-family:宋体;">的大小，</span><span style="font-family:Calibri;">0x42</span><span style="font-family:宋体;">则为</span><span style="font-family:Calibri;">redzone</span><span style="font-family:宋体;">的固定值，一共</span><span style="font-family:Calibri;">16</span><span style="font-family:宋体;">字节。在</span><span style="font-family:Calibri;">data</span><span style="font-family:宋体;">的最后同样为</span><span style="font-family:Calibri;">16</span><span style="font-family:宋体;">字节的固定值。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">由于设置</span>redzone<span style="font-family:宋体;">会占用更多的内存，同时会使初始化和释放逻辑变得复杂，从而影响效率，所以检测溢出的发生都是作为</span><span style="font-family:Calibri;">debug</span><span style="font-family:宋体;">选项来开启的。几乎所有主流的</span><span style="font-family:Calibri;">os</span><span style="font-family:宋体;">内核内存分配器在设置</span><span style="font-family:Calibri;">redzone</span><span style="font-family:宋体;">时都使用了固定值，笔者认为这也是一个不安全的设计，</span><span style="font-family:Calibri;">exploit</span><span style="font-family:宋体;">编写者可以精心构造内存结构，使其</span><span style="font-family:Calibri;">shellcode</span><span style="font-family:宋体;">地址指向</span><span style="font-family:Calibri;">0x42424242</span><span style="font-family:宋体;">，就可以绕过检测。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h4><strong><span style="font-family: 黑体;font-size: 19px;">1.3.2 UAF<span style="font-family:黑体;">检测</span></span></strong></h4><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">对于</span>UAF(Use After Free)<span style="font-family:宋体;">的检测，</span><span style="font-family:Calibri;">freebsd</span><span style="font-family:宋体;">没有实现这个功能，一般算法是在</span><span style="font-family:Calibri;">slab item</span><span style="font-family:宋体;">释放时对</span><span style="font-family:Calibri;">data</span><span style="font-family:宋体;">区域填充固定的值，在分配时先检测固定值有没有被污染，以此来判断有无</span><span style="font-family:Calibri;">UAF</span><span style="font-family:宋体;">的发生。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h4><strong><span style="font-family: 黑体;font-size: 19px;">1.3.3 <span style="font-family:黑体;">双向安全链表</span></span></strong></h4><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">双向链表的删除操作时，要先检测前后节点是否为合法地址，</span> freebsd<span style="font-family:宋体;">同样没有设计这个功能。</span></span></p><p><span style="font-family:宋体;font-size:14px;"> </span></p><h4><strong><span style="font-family: 黑体;font-size: 19px;">1.3.4 item<span style="font-family:黑体;">地址随机化</span></span></strong></h4><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;">Slab<span style="font-family:宋体;">里保存的</span><span style="font-family:Calibri;">item</span><span style="font-family:宋体;">为了初始化简单</span><span style="font-family:Calibri;">, </span><span style="font-family:宋体;">每个</span><span style="font-family:Calibri;">item</span><span style="font-family:宋体;">都是顺序链接的， 这给</span><span style="font-family:Calibri;">exploit</span><span style="font-family:宋体;">程序的利用提供了极大的方便。</span><span style="font-family:Calibri;">Linux</span><span style="font-family:宋体;">内核使用了洗牌算法将</span><span style="font-family:Calibri;">item</span><span style="font-family:宋体;">的链接顺序打乱来规避这种攻击。</span><span style="font-family:Calibri;">Freebsd</span><span style="font-family:宋体;">没有提供这个功能。</span></span></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h4><strong><span style="font-family: 黑体;font-size: 19px;">1.3.5 <span style="font-family:黑体;">管理结构体</span><span style="font-family:Arial;">cookie</span></span></strong></h4><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">同样为了检测是否有内存破坏的现象，</span> <span style="font-family:宋体;">通常会在一些管理结构体中加入一个随机化的</span>cookie<span style="font-family:宋体;">值，内存释放时判断</span><span style="font-family:Calibri;">cookie</span><span style="font-family:宋体;">是否有被污染。</span><span style="font-family:Calibri;">freebsd</span><span style="font-family:宋体;">没有提供这个功能。</span></span></p><p><br/></p>



<p><a href="2247483710">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=8a94a56d&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg4NjU1NDU4MA%3D%3D%26mid%3D2247483710%26idx%3D1%26sn%3Db91c0b55bb96ad5f3690ab64fca43780%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Mon, 11 Jan 2021 17:52:00 +0800</pubDate>
    </item>
  </channel>
</rss>