gonengazit [Lexaloffle Blog Feed]https://www.lexaloffle.com/bbs/?uid=70985 Celia - A PICO-8 TAS tool <p>Over the past few weeks I've been working on <a href="https://github.com/gonengazit/celia">Celia</a>, a TAS tool for PICO-8 based on picolove, and it's finally ready for its initial release</p> <p>Celia comes with 2 tas tools, one that should work for any PICO-8 cart (with some caveats, in the repository readme), and one that's more specialized, built for Celeste and mods. The tas tool code is layed out in a way where you can extend it to create tas tools for specific games, enhancing the normal functionality, so it also doubles as a tasing &quot;framework&quot; (api documentation coming soon).</p> <p>Celia is based on <a href="https://github.com/gonengazit/Celia">my personal fork of picolove</a>, Which has much better compatibility with PICO-8 carts than other forks, from what I've seen.</p> <p>I'd love to hear any feedback, bug reports, and feature requests/suggestions. In addition, if you make a tas using Celia, feel free to post it here, I'd love to see it!</p> <p>As a demonstration of the tas tool, I made a tas of <a href="https://www.lexaloffle.com/bbs/?tid=31538">Get Out of this Dungeon</a> by <a href="https://www.lexaloffle.com/bbs/?uid=27629"> @Insanus</a>, which you can check out here <object width="640" height="400"><param name="movie" value="https://www.youtube.com/v/00JR6MZk_ZA&hl=en&fs=1&rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="https://www.youtube.com/v/00JR6MZk_ZA&hl=en&fs=1&rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="400"></embed></object></p> <p>Happy TASing!</p> https://www.lexaloffle.com/bbs/?tid=50283 https://www.lexaloffle.com/bbs/?tid=50283 Sat, 19 Nov 2022 22:01:21 UTC Infinite token exploit <p>recently, while investigating the pico-8 preproccesor, i found some really weird behaviour, which culminated in some very strange token optimizations, and an infinite token exploit</p> <h3>Arithmetic assignment save</h3> <p>often, you want to perform multiple arithmetic operations on a varible, then assign it to itself. for example, <code>a=2*a+1</code></p> <p>the 2 ways you'd do this normally in pico-8<br /> are</p> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>a=2*a+1 -- 7 tokens a*=2 a+=1 -- 6 tokens</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>however, using preproccesor trickery, we can reduce it even more:</p> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>a*=2 +1 -- 5 tokens</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>the reason this works is because the preprocessor patching for += works line-wise, so this would be patched to</p> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>a= a*(2) +1</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <h3>Infinite token exploit #1</h3> <p>this exploit allows you to run any code that is on 1 line, and doesn't use any pico-8 preproccesor based syntax extensions (i.e. +=, shorthand if, ?), while only costing 8 tokens<br /> it works as follows:</p> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>a={} a[&quot;[t&quot;]+=&quot; &lt; your code here &gt; t(</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>this looks extremely weird, because it is. note that our code is in an (unclosed) string thus, it only counts as 1 token</p> <p>the preproccessor patches this code to </p> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>a={} a[&quot;[t&quot;] = t&quot;] + (&quot; &lt; your code here &gt; t( ) </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>we see that because of how the preproccesor parsed our expression, we don't have any unclosed strings anymore, but this still looks weird, so let's simplify it</p> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>a={} a[&quot;[t&quot;] = t(&quot;] + (&quot;) &lt; your code here &gt; t( ) </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>so, the code contains 4 parts</p> <ol> <li>creating an empty table</li> <li>assigning some value to some key in the table (not that t is the function time())</li> <li>actually running our code</li> <li>calling t()</li> </ol> <p>parts 1 2 and 4 don't actually do anything, which means we ran our code while only costing 8 tokens!</p> <h3>Infinite token exploit #2</h3> <p>the previous exploit is already nice, but being limited to 1 line is a bit annoying. so let's improve it:</p> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>a={} a['[t']+=[[' &lt; your code here &gt; t(a[a[1]] </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>is patched to </p> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>a={} a['[t'] = t'] + ([[' &lt; your code here &gt; t(a[a[1]] ) </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>similarly to exploit #1, before patching, our code is in a multiline string, and thus only costs 1 token. after patching, it is not in a string anymore, so pico8 just runs it as regular code. so now we can run any code (with the same caveat as before of not using pico-8's preproccesor based syntax extensions), using only 8 tokens</p> <h3>An argument against the preproccesor</h3> <p>all of these exploits are caused by the preproccesor being kind of weird and finnicky. while i'm sure these specific ones can be fixed by changing it, i'm pretty convinced you could find things like these in every non-syntax-aware preprocessor. while <a href="https://www.lexaloffle.com/bbs/?uid=1"> @zep</a> has been against adding compound operators (+=) to the syntax in the past, I think these examples (and all the other weird preproccesor behaviour) provide a decent argument for why it should be</p> <h3>Demo</h3> <p>to show the viability of this method, I made a version of celeste that only uses 5 tokens, using exploit #1 (the 3 token save comes from using _ENV instead of defining a)</p> <p> <table><tr><td> <a href="/bbs/?pid=0#p"> <img src="/bbs/thumbs/pico8_fivetokenleste-0.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=0#p"> fivetokenleste</a><br><br> by <a href="/bbs/?uid=0"> </a> <br><br><br> <a href="/bbs/?pid=0#p"> [Click to Play]</a> </td></tr></table> </p> https://www.lexaloffle.com/bbs/?tid=49963 https://www.lexaloffle.com/bbs/?tid=49963 Fri, 28 Oct 2022 19:51:57 UTC