<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.3.3">Jekyll</generator><link href="https://chcl.se/feed.xml" rel="self" type="application/atom+xml" /><link href="https://chcl.se/" rel="alternate" type="text/html" /><updated>2026-07-17T19:31:09+00:00</updated><id>https://chcl.se/feed.xml</id><title type="html">Dusty&apos;s Corner of the Internet</title><subtitle>Welcome to my corner of the internet.</subtitle><author><name>Dusty</name></author><entry><title type="html">Comic Sans is MIT now</title><link href="https://chcl.se/2026/07/17/comic-sans.html" rel="alternate" type="text/html" title="Comic Sans is MIT now" /><published>2026-07-17T00:00:00+00:00</published><updated>2026-07-17T00:00:00+00:00</updated><id>https://chcl.se/2026/07/17/comic-sans</id><content type="html" xml:base="https://chcl.se/2026/07/17/comic-sans.html"><![CDATA[<p>This post is a bit rushed and written with nano directly on the server, as I am on vacation, but when <a href="https://opensource.microsoft.com/blog/2026/07/16/microsoft-comic-chat-is-now-open-source/">Microsoft published Comic Chat as open source yesterday</a> they also included an era appropriate version of Comic Sans.</p>

<p>It's available directly in the repo, under <a href="https://github.com/microsoft/comic-chat/tree/f53e4b6e8e2bce7dbf3ddc7e8f12dd55591f7b17/">commit f53e4b6</a>, under "v1.0/shared/comic.ttf".</p>

<p>I've taken the liberty of exercising my rights under the license, and have uploaded a copy, together with the LICENSE, so you can also get a copy even if they remove it. <a href="/assets/comic.zip">You can download it here.</a></p>

<p>A quick legal disclaimer, so far, no statement has been made that this was done by accident, and Microsoft does own this font, so they can just release this. IANAL, but if they'd wish to claim this was an accident and that everyone should delete the files, they'd need to inform everyone - copyright law, or even contract law, does not require you to be a psychic, or second guess every license you accept, especially for something as low-value as a font from 1996.</p>

<p>If Microsoft wishes to contact me, the link is at the bottom of the page.</p>]]></content><author><name>Dusty</name></author><summary type="html"><![CDATA[This post is a bit rushed and written with nano directly on the server, as I am on vacation, but when Microsoft published Comic Chat as open source yesterday they also included an era appropriate version of Comic Sans.]]></summary></entry><entry><title type="html">Categorizing artwork</title><link href="https://chcl.se/2026/06/15/categorizing-artwork.html" rel="alternate" type="text/html" title="Categorizing artwork" /><published>2026-06-15T00:00:00+00:00</published><updated>2026-06-15T00:00:00+00:00</updated><id>https://chcl.se/2026/06/15/categorizing-artwork</id><content type="html" xml:base="https://chcl.se/2026/06/15/categorizing-artwork.html"><![CDATA[<p>The artwork gallery on this site has, for the most part, worked on the basic "safe" and "not safe for work" spectrum. However, as I stumbled upon <a href="https://gallery.bloatware.xyz/">bloatware's gallery</a>, I realized that I could sort it better.</p>

<p>I've decided to reorganize the entire gallery three tiers:</p>

<ol>
  <li><strong>Safe</strong>. This one is for the stuff that doesn't get you into trouble. It may raise eyebrows, but not get you into trouble. Yes, this includes the babyfur art.</li>
  <li><strong>Kinktimate</strong>. This one is nicked from the aforementioned gallery. Presumably a combination of "kink" and "intimate". To quote them, "Kinktimate works aren't intrinsically sexual but may be construed as being so by certain quarters."</li>
  <li><strong>Suggestive or Explicit</strong>. On account of being aro/ace, these are merged, since these images can be counted on one hand.</li>
</ol>

<p>I think this works better than the old setup. Categories are a bit unwieldy with the current system though, so I may migrate it at some point.</p>]]></content><author><name>Dusty</name></author><summary type="html"><![CDATA[The artwork gallery on this site has, for the most part, worked on the basic "safe" and "not safe for work" spectrum. However, as I stumbled upon bloatware's gallery, I realized that I could sort it better.]]></summary></entry><entry><title type="html">Another redesign - all the way to IE6</title><link href="https://chcl.se/2026/04/29/another-redesign.html" rel="alternate" type="text/html" title="Another redesign - all the way to IE6" /><published>2026-04-29T00:00:00+00:00</published><updated>2026-04-29T00:00:00+00:00</updated><id>https://chcl.se/2026/04/29/another-redesign</id><content type="html" xml:base="https://chcl.se/2026/04/29/another-redesign.html"><![CDATA[<p>Light and dark mode this time! Enjoy Baby Dusty peeking at you when browsing in light mode, even in IE6!</p>

<p><img src="/assets/postimg/remote-viewer_49ZWVL23Ih.png" alt="Screenshot of Internet Explorer 6 showing the home page in light mode." /></p>

<h2 id="how-on-earth-did-you-pull-this-off">How on earth did you pull this off?</h2>
<p>I learned some strategies as part of trying to make this nice looking on IE6. It helps that <a href="https://learn.microsoft.com/en-us/previous-versions/cc351024%28v%3Dvs.85%29?redirectedfrom=MSDN">Microsoft still has some documentation on what's supported.</a> and <a href="https://legacyupdate.net/download-center/download/18359/internet-explorer-developer-toolbar">the Developer Toolbar is archived.</a></p>

<p>While I obviously could've just used IE's weird conditional comments, that wouldn't help people trying to use other old browsers.</p>

<p><strong>First off,</strong> media queries. While the at-rule is supported since IE 5.5, an "and" rule with a query is always evaluated as false. Combine this with treating desktop as default, and it's reasonably fine. For example:</p>
<div class="language-scss highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">body</span> <span class="p">{</span>
    <span class="nl">margin</span><span class="p">:</span> <span class="m">0</span> <span class="nb">auto</span> <span class="m">0</span> <span class="nb">auto</span><span class="p">;</span>
    
    <span class="c1">// Fix the width at 770px to make sure the width is correct in IE6.</span>
    <span class="nl">width</span><span class="p">:</span> <span class="m">770px</span><span class="p">;</span>

    <span class="k">@media</span> <span class="n">screen</span> <span class="nf">and</span> <span class="p">(</span><span class="n">min-width</span><span class="o">:</span> <span class="m">1px</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// Set a dynamic width on more modern browser where that's supported and important, like phones.</span>
        <span class="nl">max-width</span><span class="p">:</span> <span class="m">770px</span><span class="p">;</span>
        <span class="nl">width</span><span class="p">:</span> <span class="m">100%</span><span class="p">;</span>
    <span class="p">}</span>
    
    <span class="k">@media</span> <span class="n">screen</span> <span class="nf">and</span> <span class="p">(</span><span class="n">max-width</span><span class="o">:</span> <span class="m">770px</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// Remove the centering margins once we're below the 770px breakpoint.</span>
        <span class="nl">margin-left</span><span class="p">:</span> <span class="m">0</span><span class="p">;</span>
        <span class="nl">margin-right</span><span class="p">:</span> <span class="m">0</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>IE6 also doesn't support child combinators (the ones like <code>div &gt; p</code>) just plain descendant selectors. Support for this was added in IE7, while media queries were added in IE9, so this can be used to apply rules specifically for that window. I don't have any such rules though.</p>

<p><strong>Second,</strong> you have to give up some of the newer semantic elements, like <code>&lt;header&gt;</code>, <code>&lt;footer&gt;</code>, and <code>&lt;nav&gt;</code>. IE6 doesn't properly nest elements under elements it's not aware of, the Developer Toolbar will show that they get parsed as separate opening and closing tags. This is most likely just a Trident quirk - IE was always famous for not parsing HTML like its peers. I replaced all of them with plain <code>&lt;div&gt;</code>s with styling based on IDs instead. Just remember to set a <code>role</code> attribute to not make people with screen readers hate you.</p>

<p><strong>Third,</strong> GIFs are surprisingly good. IE6 doesn't support transparent PNGs, and it turns out that lots of the art I have do 256-color, 1-bit alpha <em>really</em> well.</p>

<p>Other than that, not many changes were needed. I ripped out a lot of things like flexboxes back in the start of 2025 when I tried to make this site be usable in IE4, but that's for another post, involving Caddy powered crimes...</p>

<p><img src="/assets/postimg/wX2hBT3zTA.png" alt="Watson popup on Windows 95, complaining about EXPLORER causing an invalid page fault in KERNEL32.dll" /></p>

<hr />

<p>I'd like to mention that I am aware of some layout issues in IE6, specifically to do with images in posts, and the artwork page. Those aren't that trivial to fix, sadly.</p>]]></content><author><name>Dusty</name></author><summary type="html"><![CDATA[Light and dark mode this time! Enjoy Baby Dusty peeking at you when browsing in light mode, even in IE6!]]></summary></entry><entry><title type="html">Should I make another static site generator?</title><link href="https://chcl.se/2026/04/27/should-i-make-another-static-site-generator.html" rel="alternate" type="text/html" title="Should I make another static site generator?" /><published>2026-04-27T00:00:00+00:00</published><updated>2026-04-27T00:00:00+00:00</updated><id>https://chcl.se/2026/04/27/should-i-make-another-static-site-generator</id><content type="html" xml:base="https://chcl.se/2026/04/27/should-i-make-another-static-site-generator.html"><![CDATA[<p>The answer is probably no, but I still feel the yearning for it. Or maybe it's time to ditch the idea completely?</p>

<p>It's not a massive secret that I don't blog here much. Some part of it is the design - this isn't super readable for a blog, and I've never been able to style text posts in a way that I like.</p>

<p>Another part is just how complicated it is to make a post.</p>

<h2 id="introducing-jekyll">Introducing Jekyll</h2>
<p>I use a static site generator, <a href="https://jekyllrb.com/">Jekyll</a>, which isn't uncommon for nerds. How Jekyll works is fairly simple when it comes to blogs. All posts are Markdown files, stored under <code>_posts</code>. Each post has a "front matter" which sets properties on the post. For example, here is all of <code>_posts/2020-05-05-blag.md</code>:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>---
layout: post
title:  "Oh look, a blog"
date:   2020-05-05 19:54:00 +0200
---
Thought this would be better than the old single page with an image. Need some place for longer technical stuff, I suppose.

Go look at my Twitter instead. It's more exciting.
</code></pre></div></div>

<p>Immediately you may notice that making a post is a bit more complicated than just making a file and going to town in Notepad. Bare minimum, your file needs that front matter, with the "post" layout and the title. That's in fact how drafts look like - as I'm writing this post, the front matter is:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>---
layout: post
title:  "Should I make another static site generator?"
---
</code></pre></div></div>

<p>Drafts are stored in <code>_drafts</code> and are only accessible locally, when running Jekyll's internal web server.</p>

<p>Now, you may have noticed that this means there's extra work when publishing an article too. You need to move and rename the file to include the date, and add the date to the front matter. Painful.</p>

<p>I used to do all this manually, but eventually I wrote a shell script, <code>tool.sh</code>, which does this for me. Now I get to make posts with a simple <code>./tool.sh newpost "Should I make another static site generator?"</code> and publish them with a simple <code>./tool.sh publish "Should I make another static site generator?"</code>. After that all I need to do is a <code>git commit</code> and a <code>git push</code>, and the GitLab pipeline will deploy it to my site.</p>

<p>At this point, I hope anyone who is using something more modern, like <em>Blogger circa 2004</em>, are screaming and pulling their hair out over this workflow.</p>

<p>To reiterate, to write a post I have to:</p>
<ol>
  <li>Start my computer.</li>
  <li>Open Visual Studio Code.</li>
  <li>Run a shell script to create a post.</li>
  <li>Write the actual post.</li>
  <li>Run the shell script again to publish the post.</li>
  <li>Commit the published post.</li>
  <li>Push it to the repository where GitLab will start a worker to build it into a website, and put it on my server.</li>
</ol>

<p>Can you guess why I'm not making any posts? After all, the best ideas come when you're half asleep, or on the shitter. I'm not bringing a computer with me on the shitter.</p>

<h2 id="do-i-need-jekyll">Do I need Jekyll?</h2>
<p>Jekyll gives you a decent blog out of the box, with <a href="https://jekyll.github.io/minima/">the Minima theme</a>. Embed tags, site map, RSS, you got it. You may not believe it, <em>I'm still using Minima under the hood on this site,</em> there's just a lot of overridden templates.</p>

<p>However, over the years, I've ripped out more and more of the Jekyll plugins, and replaced them with templates.</p>

<p>The sitemap plugin didn't account for changes to templates, but rather just the post itself, so <code>tool.sh</code> now pulls dates from the git history, puts it in a YAML file, and lets Jekyll handle filling in a sitemap.xml template.</p>

<p>The "SEO" plugin generated lackluster embeds and metadata for the artwork section, so it was removed as well, and replaced with roughly 100 lines of template spaghetti.</p>

<p>At this point Jekyll doesn't really bring much to the table, beyond being something that applies templates. In a way, this is the strength of Jekyll - it's very flexible, and could be used for all kinds of sites. It's <a href="/2024/08/23/artwork.html">how I can generate an artwork gallery</a>.</p>

<p>So, no, I don't really need Jekyll. Anything that can do templating and Markdown will work.</p>

<h2 id="do-i-need-it-to-be-static-in-the-first-place">Do I need it to be static in the first place?</h2>
<p>This is a more complicated question. The nice thing is that it's very "fire and forget" once built. It's much harder to compromise a pile of files on a dumb web server, compared to something with a login system and fully featured dashboard.</p>

<p>However, you'll never get over everything having to have a separate "build and deploy" step when you're not serving directly from the source. That means you can never realistically use an app for writing posts, because it's unlikely you'll find a git server that supports <a href="https://web.archive.org/web/20080307032943/http://www.xmlrpc.com/metaWeblogApi">MetaWeblog</a> which is an extension of the <a href="https://web.archive.org/web/20030202024439/http://plant.blogger.com/api/index.html">Ancient Blogger API</a>.</p>

<p>The downside to leaving the static site generation world is that I'll need to move the blog to a different subdomain. My site stays usable down to IE6 without any JavaScript - I doubt that any modern fully featured blogging solution will do that, if it even lets me do things like an artwork gallery.</p>

<h2 id="final-thoughts">Final thoughts</h2>
<p>Maybe the way forward is to have a separate blog, and just modify the main site by hand. Or maybe implement MetaWeblog as a daemon that can handle all the committing, renaming, and pushing for me. Regardless, if I want post more often, I probably need to change something.</p>

<hr />

<p>I actually wrote <a href="https://github.com/ChlorideCull/ChlorideSiteGenerator">a very basic and kinda bad static site generator back in 2013</a>. Maybe I should revive it? :D</p>

<p>Also, as a funny aside, I would've probably changed the name of this post if it wasn't painful to do so.</p>]]></content><author><name>Dusty</name></author><summary type="html"><![CDATA[The answer is probably no, but I still feel the yearning for it. Or maybe it's time to ditch the idea completely?]]></summary></entry><entry><title type="html">PhisonTool - reverse engineering a toolkit</title><link href="https://chcl.se/2025/07/14/phisontool.html" rel="alternate" type="text/html" title="PhisonTool - reverse engineering a toolkit" /><published>2025-07-14T18:07:51+00:00</published><updated>2025-07-14T18:07:51+00:00</updated><id>https://chcl.se/2025/07/14/phisontool</id><content type="html" xml:base="https://chcl.se/2025/07/14/phisontool.html"><![CDATA[<p>Phison is a taiwanese manufacturer of USB flash drive controllers - they are extremely simple for manufacturers to use, just wire up a NAND chip, flash the firmware, and off you go! This means you'll find this controller in most USB flash drives, cheap or not.</p>

<p>The controllers are capable of lots of things - most notably, emulating a CD reader. Sadly, using that functionality isn't that easy. Changing most of the properties with official tools require a full reflash, and finding firmware (which is unique to the NAND model used!) isn't easy. You can <em>kinda</em> use another tool call ModeConverter to change it, but it changes a lot of stuff in the process.</p>

<p><em>Note: This post is kinda rough. I blame the fact that my apartment has been 30 degrees celsius over the last two days.</em></p>

<p>So, where to start? Well, we should start by looking for information others have already gathered! Searching for a bit will reveal a couple key things:</p>
<ul>
  <li><a href="https://gist.github.com/warewolf/e19d6817f1d59939a32fbd9e1a30b9d2">A gist accompanying a talk at Shmoocon 2014</a>, with links to slides that dive a bit into the internals.</li>
  <li><a href="https://www.usbdev.ru/files/phison/">usbdev.ru</a> - Russian site containing a lot of guides, and, importantly, leaked versions of MPALL, which is the official vendor flashing software.</li>
  <li><a href="https://github.com/brandonlw/Psychson">brandonlw/Psychson on Github</a> - Repo with tools related to running custom firmware on a Phison controller to enable BadUSB attacks.</li>
</ul>

<p>Skimming through these, you'll find out that it uses vendor specific SCSI commands, and using them I was able to start by implementing a command to dump:</p>
<ul>
  <li>An "unknown page" with <code>06 05 'R' 'D' 00 00</code>...</li>
  <li>"Vendor Info" with <code>06 05 00 00</code>...</li>
  <li>"Vendor Info 2" with <code>06 05 'I' 'N' 'F' 'O' 00 00</code>...</li>
  <li>"Flash Identification Block" with <code>06 56 00 00</code>...</li>
</ul>

<p>Additionally, I implemented a command to restore (or flash) "Vendor Info 2" with <code>06 06 01 00 00</code>...
I also added in Read/Write XData, although I haven't looked into it much.</p>

<p>Once I had my "virgin" dump safely copied away, I could fire up Wireshark with USBpcap, and start running tools while looking at the commands. Using <a href="https://imhex.werwolv.net/">ImHex</a>, I could diff dumps of "Vendor Info 2" where most things seemed to happen, and document fields as I discover them in the pattern editor.
To my surprise, several tools just trampled existing fields, but the firmware seemed to cope fine. Hence I restored that "Vendor Info 2" a lot.</p>

<p>Repeated restores, captures, and tool wrangling culminated in me successfully being able to manually write an ISO image, and then hex edit "Vendor Info 2" to flip it over to CD emulation mode.</p>

<video controls="" width="934">
    <source src="/assets/postimg/phisontool/explorer_GNzHQRhExy.mp4" type="video/mp4" />
</video>

<h2 id="what-now">What now?</h2>

<p><a href="https://github.com/ChlorideCull/PhisonTool">The code is on Github</a>, and I'll implement "Vendor Info 2" editing later. The biggest limit is a lack of dumps, so please, submit them - just get in touch.</p>]]></content><author><name>Dusty</name></author><summary type="html"><![CDATA[Phison is a taiwanese manufacturer of USB flash drive controllers - they are extremely simple for manufacturers to use, just wire up a NAND chip, flash the firmware, and off you go! This means you'll find this controller in most USB flash drives, cheap or not.]]></summary></entry><entry><title type="html">Cracking Enterprise Software for Fun and no Profit</title><link href="https://chcl.se/2024/09/14/cracking-enterprise-software-for-fun-and-no-profit.html" rel="alternate" type="text/html" title="Cracking Enterprise Software for Fun and no Profit" /><published>2024-09-14T00:00:00+00:00</published><updated>2024-09-14T00:00:00+00:00</updated><id>https://chcl.se/2024/09/14/cracking-enterprise-software-for-fun-and-no-profit</id><content type="html" xml:base="https://chcl.se/2024/09/14/cracking-enterprise-software-for-fun-and-no-profit.html"><![CDATA[<p>Ever since I was a broke teen, I've had an interest in reverse engineering software, and cracking it. I've always been one of those weird people who want to run a bunch of enterprise software.</p>

<p><em>I've censored company and product names, mostly because I don't want to end up high on Google when you search for "Company A crack". Also, as I post this, I've updated the theme to increase readability, and done a quick design pass on the code blocks. Feedback welcome.</em></p>

<h1 id="legalities">Legalities</h1>
<p>I'll start with the obvious - <strong>I haven't actually made a crack in about 10 years, and I no longer have any devices with those cracks on them.</strong> Now that police and lawyers have no more reason to read...</p>

<p>When talking about whether something is legal in practice, there are two factors to consider.</p>

<h2 id="legal-liability">Legal liability</h2>
<p>Your legal liability is the laws and agreements you break, and how fucked you are if arrested or sued.</p>

<p>This is one of the more complex topics, and generally something to approach Legal over if you're doing this as part of a company.</p>

<p><strong>In the European Union,</strong> you are largely going to operate under <a href="https://eur-lex.europa.eu/legal-content/EN/TXT/HTML/?uri=CELEX:32009L0024#d1e303-16-1">Article 5 § 3 of Directive 2009/24/EC, which grants exceptions to the rights enumerated in Article 4</a>. Fundamentally, it means that if you have the right to use a program, you have the right "to observe, study or test the functioning of the program in order to determine the ideas and principles which underlie any element of the program if he does so while performing any of the acts of loading, displaying, running, transmitting or storing the program which he is entitled to do", even without the permission of the rightsholder.</p>

<p>Important thing to note there is "<em>any of the acts of loading, displaying, running, transmitting or storing the program which he is entitled to do</em>" which means you're severely limited on what you're actually allowed to do - you may not decompile code, for example. At least <a href="https://curia.europa.eu/juris/document/document.jsf?text=&amp;docid=247056&amp;pageIndex=0&amp;doclang=EN&amp;mode=lst&amp;dir=&amp;occ=first&amp;part=1&amp;cid=10200757">case law allows you to decompile software in order to fix bugs</a>.</p>

<p>But, this is nuanced, I am not a lawyer, and if you care about this part, you need to ask one. I usually rely on the second factor.</p>

<h2 id="enforcement">Enforcement</h2>
<p>This one is pretty simple - will the police come to arrest you, or will the company sue you?</p>

<p>First of all, if you're running around cracking shit, and constantly uploading them under a pseudonym, the police is going to come knocking on your door. <strong>Don't do that. Don't distribute cracks, use it as a learning opportunity at best.</strong></p>

<p>Second, if you're doing things as part of your job, and your company is paying their license fees, and there's no way paying more money to the software company solves the problem, they probably don't care. Suing your customers is bad for business.</p>

<p>For example, say <strong>Company A</strong> makes some enterprise software that your company has purchased, which is used on an automatically provisioned machine. This has a DRM system that requires manually authorizing and deauthorizing it, or you have to contact their support to have a license key reissued. Your company has a policy that all automatically provisioned machines must be replaced monthly. Figuring out how this DRM ticks, and how to transfer the registration is <em>technically</em> against the license agreement, but in the end, <strong>Company A</strong> does not offer floating licenses, you're not using it on more machines than what you pay for, and you don't have to contact their support every three months because the machine got wiped before you could deauthorize it. Not that I would know.</p>

<p>Next, if you're cracking some enterprise software for your homelab, and not distributing the crack, most companies <strong>really</strong> don't care. If their minimum price is five digits USD, or "contact us", you're not a potential customer with your clapped out Dell PowerEdge that's 10 years out of support and requires an old version of Java 8 to run the remote KVM.</p>

<p>Some companies are more litigious though. You probably don't want to invite the trouble of any company whose running joke is that they have a bigger legal department than they have R&amp;D.</p>

<h1 id="why-enterprise-software">Why Enterprise Software?</h1>
<p>Now that we've gone over legalities and your risk, and you've decided you want to try this, either as a first reverse engineering stint, or to try out making cracks, <em>why enterprise software?</em></p>

<p>The simple answer is that copyright protection, DRM, whatever you want to call it, is a cost. Companies really don't want to spend more money on it than they have to, and for regular consumer software, they have to. All you have to do to see why is to use Google. <em>CensoredEnterpriseProduct "crack"</em> returns 11900 results, while <em>CensoredDeveloperProduct "crack"</em> returns 71500 results.</p>

<p>What this means in practice, is that enterprise software tends to not have obfuscation, or a bunch of third party tools trying to make your life harder. I've seen plenty of enterprise software ship with a class called <code>LicenseManagement</code> that has a function called <code>Verify</code>. You'll never find this in regular consumer software. This is great for getting started.</p>

<p>However, unlike a lot of customer software, they are snitches.</p>

<h2 id="snitches">Snitches?</h2>
<p>Enterprise software loves to snitch on the people running them. They will print licensing information in places obvious, in places non-obvious, and in some cases, especially for hosted software, have undocumented API endpoints that reveal enough information about the license key used that the software company can even scan the internet for improperly licensed instances.</p>

<p>The one thing they tend to not do, is call home. Enterprise comes with weird requirements and obstacles in deployment, and calling home is a sore subject at times. Usually, it's solved by enabling audits though the license signed when buying the software instead.</p>

<p>In other words, if you're cracking some enterprise software to run in a lab, don't expose it on the internet. It will probably rat you out.</p>

<h2 id="the-novelty">The Novelty</h2>
<p>Enterprise software is rarely looked at and appreciated - they are bought by higher ups in suits, and employees are forced to use them in their day to day work. Some of them are quite different when viewed from a different light - the technical side that enables it, using it when you feel like it, and exploring the possibilities and downright weird features that you know were added because of some requirement from a big customer.</p>

<p>It's a new frontier for technical exploration. Give it a shot.</p>]]></content><author><name>Dusty</name></author><summary type="html"><![CDATA[Ever since I was a broke teen, I've had an interest in reverse engineering software, and cracking it. I've always been one of those weird people who want to run a bunch of enterprise software.]]></summary></entry><entry><title type="html">Artwork gallery for commissions</title><link href="https://chcl.se/2024/08/23/artwork.html" rel="alternate" type="text/html" title="Artwork gallery for commissions" /><published>2024-08-23T19:28:00+00:00</published><updated>2024-08-23T19:28:00+00:00</updated><id>https://chcl.se/2024/08/23/artwork</id><content type="html" xml:base="https://chcl.se/2024/08/23/artwork.html"><![CDATA[<p>I've created an artwork gallery for all my commissions, as well as spiffed up the styling a bit. Feel free to take a look - and see below for a behind the scenes look on how it's done.</p>

<h2 id="behind-the-scenes">Behind the scenes</h2>
<p>As you might know by now, this site uses Jekyll. All artwork is stored in a "collection" defined in <code>_config.yml</code>, set to output the individual documents:</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">collections</span><span class="pi">:</span>
  <span class="na">artists</span><span class="pi">:</span>
  <span class="na">artwork</span><span class="pi">:</span>
    <span class="na">output</span><span class="pi">:</span> <span class="kc">true</span>
</code></pre></div></div>
<p>There is also an "artists" collection used to store artist information.</p>

<p>To use <a href="/artwork/alby-natures-child.html">"Nature's Child" by Alby</a> as an example:</p>

<p>There is an <code>_artwork/alby-natures-child.md</code> file that contains the metadata:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>---
title: "Nature's Child"
author: "Alby"
date: "2024-08-19"
desc: "A young Dusty out in nature, wearing red overalls, peeking over a fence."
categories:
  - safe
---
</code></pre></div></div>
<p>and then the actual image is stored as <code>_artwork/alby-natures-child.png</code>.</p>

<p>There is also an <code>_artists/alby.md</code> file that contains the metadata for Alby themselves:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>---
title: "Alby"
site: "https://albys.space/"
---
</code></pre></div></div>

<p>Next, in <code>_config.yml</code>, there is a default layout set for all documents under the artwork collection:</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">defaults</span><span class="pi">:</span>
  <span class="pi">-</span>
    <span class="na">scope</span><span class="pi">:</span> 
      <span class="na">path</span><span class="pi">:</span> <span class="s2">"</span><span class="s">_artwork"</span>
    <span class="na">values</span><span class="pi">:</span>
      <span class="na">layout</span><span class="pi">:</span> <span class="s">artwork</span>
</code></pre></div></div>
<p>This means that Jekyll will use <code>_layouts/artwork.html</code> to generate the actual document. I'll skip the majority of the document, but there are a couple of snippets that perform some magic:</p>

<p>First, this snippet finds the artist from the artists collection, and makes sure to link their site.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{%- assign artist = site.artists | find: "title", page.author -%}
&lt;h2 class="artwork-artist" itemprop="author copyrightHolder" itemscope itemtype="http://schema.org/Person"&gt;&lt;a href="{{ artist.site }}" itemprop="name"&gt;{{ artist.title }}&lt;/a&gt;&lt;/h2&gt;
</code></pre></div></div>

<p>Second, this snippet digs out the corresponding file and sticks it in an img tag.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{%- assign artwork_collection = site.collections | find: "label", "artwork" -%}
{%- assign artwork_file = artwork_collection.files | find: "basename", page.slug -%}
&lt;img src="{% link {{artwork_file.path}} %}" alt="{{page.desc}}"&gt;
</code></pre></div></div>

<p>The artwork indices are made in the same way, roughly.</p>

<p>That's about it for how things are set up right now.</p>]]></content><author><name>Dusty</name></author><summary type="html"><![CDATA[I've created an artwork gallery for all my commissions, as well as spiffed up the styling a bit. Feel free to take a look - and see below for a behind the scenes look on how it's done.]]></summary></entry><entry><title type="html">.well-known/button.json support!</title><link href="https://chcl.se/2024/08/05/button.html" rel="alternate" type="text/html" title=".well-known/button.json support!" /><published>2024-08-05T14:57:10+00:00</published><updated>2024-08-05T14:57:10+00:00</updated><id>https://chcl.se/2024/08/05/button</id><content type="html" xml:base="https://chcl.se/2024/08/05/button.html"><![CDATA[<p>I've just added support for <a href="https://codeberg.org/LunarEclipse/well-known-button"><code>/.well-known/button.json</code></a> with a button of my own.</p>

<p><a href="/"><img src="/assets/88x31.gif" alt="An image of an orange furry dragon on a purple gradient background, next to it is 'Dustys Corner' written in highly legible cursive, bouncing." /></a></p>

<p>This site uses Jekyll, so I basically just created the file manually where it should be, and explicitly included <code>.well-known</code> in the config.</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">include</span><span class="pi">:</span>
  <span class="pi">-</span> <span class="s">.well-known/</span>
</code></pre></div></div>]]></content><author><name>Dusty</name></author><summary type="html"><![CDATA[I've just added support for /.well-known/button.json with a button of my own.]]></summary></entry><entry><title type="html">Analyzing a prolific adware downloader</title><link href="https://chcl.se/2023/08/30/girlsmist.html" rel="alternate" type="text/html" title="Analyzing a prolific adware downloader" /><published>2023-08-30T16:23:10+00:00</published><updated>2023-08-30T16:23:10+00:00</updated><id>https://chcl.se/2023/08/30/girlsmist</id><content type="html" xml:base="https://chcl.se/2023/08/30/girlsmist.html"><![CDATA[<p>Let me start with the TL;DR; - <em>there's an adware network that's been running since at least 2015, and is still active today. I start pulling on the thread by analyzing an infected file from 2018</em>.</p>

<p>Every now and then I stumble upon some old piece of malware, which has tagged along for years without anyone really caring, especially if it no longer works.</p>

<p>This downloader has proliferated on torrent sites for years, especially in keygens which traditionally have a high false positive rate. Needless to say, AV vendors tend to not care about false positives in warez.</p>

<p>The sample I'm analyzing is a keygen for some software - SHA256: <code>f9dcc16f68be2a69df7bcbab6be54a87daaafa1f2b49ca3557da732abb12b8f8</code>. <a href="https://www.virustotal.com/gui/file/f9dcc16f68be2a69df7bcbab6be54a87daaafa1f2b49ca3557da732abb12b8f8">Here is the VirusTotal report.</a></p>

<h2 id="digging-in">Digging in</h2>

<p>A quick glance at the binary shows that it's based on NSIS. Using a <a href="https://github.com/myfreeer/7z-build-nsis/releases">special build of 7zip</a> you can decompile the NSIS script, to try to find out what it's doing.</p>

<p>7zip can also extract files from an NSIS installer, which means we get to see what's inside - it's incredibly bare, with three files inside $PLUGINSDIR. Two DLLs,</p>
<ul>
  <li>nsisdl.dll (<code>A1E09FB1739EF7557D18104B0D6A4C7725E1EC293F5404C80402F57FF9EBB9D0</code>)</li>
  <li>System.dll (<code>A0CAC4CF4852895619BC7743EBEB89F9E4927CCDB9E66B1BCD92A4136D0F9C77</code>)</li>
</ul>

<p>are genuine DLLs from NSIS 3.03. There is a file named "B" in this directory as well, helpfully carrying a modification date showing when infection occurred. 2018-10-07, in my sample.</p>

<p>The NSIS script is relatively simple, with some obfuscation we can basically ignore as it's only for decoding the information retrieved from the Command and Control servers, which are long down. The flow is basically as follows:</p>

<ol>
  <li>The scripts uses nsisdl to attempt to download a payload descriptor to <code>$PLUGINSDIR\&lt;10 random characters&gt;</code>, first <code>http://strong.girlsmist.online/lvx7.php?p=sevenzip&amp;tid=...&amp;pid=...&amp;n=...&amp;b_typ=pe</code> and then <code>http://pepper.cobwebdesign.host/lvx7.php?p=sevenzip&amp;tid=...&amp;pid=...&amp;n=...&amp;b_typ=pe</code>. There's a timeout of 5 seconds on each, and the installer gracefully continues if both fail.</li>
  <li>The payload descriptor is decoded in that obfuscated snippet of code to a URL for the payload, and a flag for how to handle the payload.</li>
  <li>Depending on the flag, it performs the following:
    <ul>
      <li>If the flag is <code>boot</code>, the URL is downloaded to <code>$TEMP/&lt;10 random characters&gt;.exe</code> and a "Windows Refresh" key is placed in <code>HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce</code>, pointing to the exe. This will make the payload run on boot. After this the "B" file is renamed to "setup.exe" and executed.</li>
      <li>If the flag is <code>first</code>, the URL is downloaded to <code>$PLUGINSDIR\&lt;10 random characters&gt;</code>, and executed. After this the "B" file is renamed to "setup.exe" and executed.</li>
      <li>If the flag is <code>only</code>, the URL is downloaded to <code>$PLUGINSDIR\&lt;10 random characters&gt;</code>, and executed. <strong>The "B" file is never executed.</strong></li>
      <li>If the flag is <code>last</code>, the URL is downloaded to <code>$PLUGINSDIR\&lt;10 random characters&gt;</code>, the "B" file is renamed to "setup.exe" and executed, and then, finally, the earlier downloaded payload is executed.</li>
    </ul>
  </li>
</ol>

<p>Helpfully, my sample contained <em>another sample</em>. No clue why - could be to double dip on payments for dropping malware/adware, or a genuine mistake. This was great for figuring out what's random and what's constant, however.</p>

<h2 id="indicators">Indicators</h2>

<p>There's a very obvious indicator for compromise - binaries named <code>&lt;10 random characters&gt;.exe</code> running under <code>%TEMP%</code>, so I'll focus on identifying infected files instead, and specifically this strain of this family. This is all byte sequences or strings found in the infected binary on disk.</p>

<ol>
  <li>
    <p><code>03 9A 80 5C 42 2D 3E 03 9A 80 5C 73 65 74 75 70 2E 65 78 65</code> ("$PLUGINSDIR\B -&gt; $PLUGINSDIR\setup.exe" rename string in NSIS script)</p>
  </li>
  <li>
    <p><code>53 4F 46 54 57 41 52 45 5C 4D 69 63 72 6F 73 6F 66 74 5C 57 69 6E 64 6F 77 73 5C 43 75 72 72 65 6E 74 56 65 72 73 69 6F 6E 5C 52 75 6E 4F 6E 63 65 00 57 69 6E 64 6F 77 73 20 52 65 66 72 65 73 68 00</code> (SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce and "Windows Refresh" next to each other in the NSIS script string table)</p>
  </li>
  <li>
    <p><code>03 99 80 5C ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 2E 65 78 65 00</code> <strong>and</strong> <code>03 9A 80 5C ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 2E 65 78 65 00</code>
($TEMP\??????????.exe and $PLUGINSDIR\??????????.exe in NSIS script string table - the unknown bytes are the same in both entries)</p>
  </li>
  <li>
    <p><code>03 9A 80 5C ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 00</code>
($PLUGINSDIR\?????????? in NSIS script string table - unknown bytes are different from the ones that would be used above)</p>
  </li>
  <li>
    <p><code>http://strong.girlsmist.online/lvx7.php?p=sevenzip</code> (C2 server 1)</p>
  </li>
  <li>
    <p><code>http://pepper.cobwebdesign.host/lvx7.php?p=sevenzip</code> (C2 server 2)</p>
  </li>
  <li>
    <p><code>.php?p=sevenzip&amp;tid=</code> or <code>.php?p=sevenzip&amp;pid=</code> (Generic detection of all strains I've found so far)</p>
  </li>
</ol>

<h2 id="unwrapping-an-infected-file">Unwrapping an infected file</h2>

<p>It's relatively trivial to recover the original file that's been infected - just open the infected file with 7zip, and extract <code>$PLUGINSDIR\B</code>. <strong>Note that there could be multiple layers of infection</strong>, so you should check if the file you extracted also contains a <code>$PLUGINSDIR\B</code>.</p>

<h2 id="so-where-did-this-come-from">So, where did this come from?</h2>

<p>As far as I can tell, this is not the first strain of its kind, nor its last.</p>

<p><a href="https://www.trendmicro.com/vinfo/ae/threat-encyclopedia/malware/CRCK_KEYGEN.SM/">In early 2017, TrendMicro analyzed something similar as 'CRCK_KEYGEN.SM'</a>, given it is said in the technical details that it tries to connect to similar servers (same parameters). Once again, we see that whole "AV vendors doesn't care about that side of the internet" thing - I'd put "tries to download and run arbitrary code" above "is a keygen", but c'est la vie.</p>

<p>There's a <a href="https://giantpanda.gtisc.gatech.edu/malrec/pcap/f91dd04e-0b80-47c0-8720-229a5cd17bfe.pcap">pcap from a 2015 relative</a> available, as well.</p>

<p>To my surprise, <strong>this campaign is still active</strong> - <a href="https://www.virustotal.com/gui/file/ac6b725d3c4942c3f72ac4296868850bd1eddec2ea5fddfb0b860fdab855945e">I can find samples still calling URLs with a related set of parameters</a>, now to <code>pe-mainin.com</code>. Thanks to <a href="https://otx.alienvault.com/indicator/domain/pe-mainin.com">AlienVault</a> keeping old whois data around, we can see that it's <a href="https://wakenet.se/">Wakenet AB</a> who's most likely behind it. Very conventiently, <a href="https://web.archive.org/web/20230830161213/http://pe-sixi.com/">pe-sixi.com, also linked to Wakenet, is hosting a fake 7zip download page at the moment, calling it "SevenZip"</a>. Through this, it's related to "C4DL Media", and P2Pcontrol.</p>

<h2 id="where-next">Where next?</h2>

<p>There's a lot of unanswered questions. Who is/was infecting a ton of keygens and uploading them, for example?</p>

<p>While I wish I could go into more depth on more recent samples, I don't have access to download samples from VirusTotal or Hybrid Analysis, by virtue of doing this on my spare time.</p>]]></content><author><name>Dusty</name></author><category term="reverse engineering" /><category term="cybersecurity" /><summary type="html"><![CDATA[Let me start with the TL;DR; - there's an adware network that's been running since at least 2015, and is still active today. I start pulling on the thread by analyzing an infected file from 2018.]]></summary></entry><entry><title type="html">My #CheapPCChallenge2022 entry</title><link href="https://chcl.se/2022/12/22/cheap-pc-challenge.html" rel="alternate" type="text/html" title="My #CheapPCChallenge2022 entry" /><published>2022-12-22T12:37:14+00:00</published><updated>2022-12-22T12:37:14+00:00</updated><id>https://chcl.se/2022/12/22/cheap-pc-challenge</id><content type="html" xml:base="https://chcl.se/2022/12/22/cheap-pc-challenge.html"><![CDATA[<p>As I'm writing this, I've just finished with the scoring benchmarks for my entry to Shyra's <a href="https://www.youtube.com/watch?v=JqpAJiTUymI">#CheapPCChallenge2022</a>. I decided to go for something a bit extreme - taking the word cheap to the next level - and plenty of spanners were thrown in the works along the way. I'm surprised I got it as far as I got it!</p>

<h1 id="beginning">Beginning</h1>

<h2 id="day-1---23rd-of-november">Day 1 - 23rd of November</h2>
<p>I found out about this whole challenge a bit late. 22 days after it started, in fact. I went onto the local auction site, and proceeded to bid home an HP Elite 8300 SFF charitably described by the seller as "defective" - the DVD drive is broken, the case is mangled, and worst of all, it completely fails to load BIOS, causing the EC to spin up the fans after a minute as a safety measure. I also bid home an R9 280X, but that ended up irrelevant in the end - we'll get to that when we come to that.</p>

<p><img src="/assets/postimg/cheap_pc_challenge_2022/pc_purchase.png" alt="Receipt for the PC, showing a cost of 145 SEK" /></p>

<p><em>Current budget spent: 145 SEK / ~1000 SEK</em></p>

<h2 id="day-7---29th-of-november">Day 7 - 29th of November</h2>
<p>I finally got the cheap computer, and boy, was it broken. The Embedded Controller was completely unresponsive - I spent a couple hours trying to revive it, to no avail. It sure was mangled though.</p>

<p><img src="/assets/postimg/cheap_pc_challenge_2022/mangled.JPG" alt="Photo of the rear expansion slot brackets - one is missing and two are bent." /></p>

<p>There was also a broken inductor right next to the Intel Ethernet IC, so you can guess how well that IC was working.</p>

<p><img src="/assets/postimg/cheap_pc_challenge_2022/broken_inductor.JPG" alt="Photo of the broken inductor. The coil is partially unspooled, and dangling in the air. It no longer has continuity." /></p>

<p>I did, however, order some RAM (open box deal) and a brand new SSD (literally the cheapest one available). I could've sourced it through eBay for cheaper, but, again, we'll get to that later.</p>

<p><img src="/assets/postimg/cheap_pc_challenge_2022/inet_purchase.png" alt="Receipt for the RAM and SSD, showing a cost of 399 + 239 SEK" /></p>

<p>At this point, I also noticed the configuration this machine shipped with - the signs of its past life. It's genuinely the first time I've seen a machine in the wild that shipped with FreeDOS. It's also been professionally refurbished, and has a (sadly damaged) Windows 10 Pro for Refurb PCs COA. If you figure out the serial key, let me know.</p>

<p><img src="/assets/postimg/cheap_pc_challenge_2022/past_life.JPG" alt="Sticker that shows that the machine shipped with FreeDOS. Above it is a torn Windows 10 Pro for Refurbished PCs COA." /></p>

<p><em>Current budget spent: 783 SEK / ~1000 SEK</em></p>

<h2 id="day-9---1st-of-december">Day 9 - 1st of December</h2>
<p>I manage to get the EC to start by performing a hard reset of it, which involves removing all sources of power, holding the "Clear CMOS" button for a minute, and holding the power button for a minute, to really drain everything.</p>

<p>Going by the word of the seller, I also try to connect my SPI flasher to the BIOS chip on the motherboard - I was able to order a clip from Amazon before I got the computer <a href="https://www.tachytelic.net/2022/01/hp-compaq-8300-nvme/">thanks to this helpful post showing where it is and what clip I needed ahead of time.</a> This failed spectacularly, because a dirt cheap SOIC-16 clip from Amazon has the rigidity of a wet noodle, and the plastic got chewed up instantly.</p>

<p>I ended up placing an order on Mouser for a €30 Pomona IC clip, a couple replacement inductors to try to replace the broken one, and a couple replacement flash ICs, in case it was broken.</p>

<h2 id="day-10---2nd-of-december">Day 10 - 2nd of December</h2>
<p>I got the package with the RAM, unsurprisingly it did not boot. It was at this weekend I decided to visit my parents, and managed to get COVID.</p>

<p>For those of you wondering - I had pretty mild symptoms, except my sense of smell and taste got pretty messed up. Gasoline smelled like broccoli, for some reason. The biggest issue was the brain fog.</p>

<h2 id="day-22---14th-of-december">Day 22 - 14th of December</h2>
<p>Finally having some energy back after COVID, I slowly started tackling this PC again. I dumped the flash with the SPI flasher and the new IC clip (which was well worth the money), and transplanted over the unique regions I knew of back into an image pulled from the most recent update. My theory was that the previous owner had tried to downgrade the BIOS, which bricks it, or that an upgrade had bricked it, which is common enough that you have people asking about it on the support forums.</p>

<p>When it still didn't boot, I decided to rip off the bandaid, and looked at the one place I hadn't looked - under the CPU. <strong>I hate this god damn mechanism.</strong> It's fragile, the off-kilter pressure gives bad heatsink contact, and it's hard to even spot if a pin is bent. And guess what? Eventually, I spotted two bent pins. One was right next to another one of the same net, so it probably would be fine, but the other one was the sole VCCIO pin on that part of the chip.</p>

<p>Ready to give up, I threw caution to the wind, and attacked it with some fine electrical pliers out of my iFixit kit. <strong>Miraculously, I managed to bend the straight up broken VCCIO pin to a location where it would contact the pad on the CPU.</strong></p>

<p><img src="/assets/postimg/cheap_pc_challenge_2022/it_lives.jpg" alt="The &quot;Non-system disk or disk error&quot; message shown when it can't find a disk to boot from" /></p>

<p>I have never been this happy to see this stupid message.</p>

<p><a href="/assets/postimg/cheap_pc_challenge_2022/3623baa7cf312e11.png">You can see which pin I "fixed" and which was left broken, by looking at this map.</a> I fixed M13, while J4 was left as-is.</p>

<p>This left me with a conundrum - because I suddenly had a chance at finishing this, but I was missing the special cable used to get SATA power from the motherboard, since the proprietary power supply routes that through the motherboard to make it easier to swap. I also had no way of powering the GPU.</p>

<h2 id="day-29---21st-of-december">Day 29 - 21st of December</h2>
<p>In another burst of energy, I tried replacing the broken inductor, but my soldering iron's skinny tip couldn't even start heating up the solder. Annoying, but I had <em>somewhat</em> planned for this. We'll get to that later.</p>

<p>I also now realized that the flash is now in a weird mode where it reboots three times before it starts. It also always boots when powered up, no matter the settings. I also managed to wipe the model name from the BIOS. Whoops.</p>

<h2 id="day-30---22nd-of-december">Day 30 - 22nd of December</h2>
<p>Using a PSU I dug out of the electronics recycling bin near my apartment in mid-November, I fired up the machine with the SSD, and installed Windows 10. I wouldn't recommend using random PSUs with cut cables from a recycling bin, but I had the fire extinguisher nearby :)</p>

<p><img src="/assets/postimg/cheap_pc_challenge_2022/jury_rigged.JPG" alt="Photo of the PC, with a second power supply on top of the original one." /></p>

<p>If you're eagle eyed, you might spot that there's a network card in there. You see, according to the rules of the challenge, you're only supposed to use parts acquired after the challenge started. That network card is 5+ years old at this point. Thing is - I ordered one for this machine, but it won't get here until the start of January because of eBay's "Global Shipping Program". You know, <a href="https://www.youtube.com/watch?v=35ntO9rmDzw">the program known for destroying whatever is sent through it.</a></p>

<p>This is a TP-Link TG-3468, and is generally what I go for when it comes to "needs a Gbps capable network card". I bought one for £5 - I'll be counting that into the budget, and you'll just have to pretend this card is that identical card.</p>

<p>Hoping that doesn't disqualify me, here's the results!</p>

<h1 id="results">Results</h1>

<table>
    <tr>
        <th>Item</th>
        <th>Cost</th>
        <th>Cost USD</th>
    </tr>
    <tr>
        <td>Base PC</td>
        <td>145 SEK</td>
        <td>$13.90</td>
    </tr>
    <tr>
        <td>RAM</td>
        <td>399 SEK</td>
        <td>$38.26</td>
    </tr>
    <tr>
        <td>SSD</td>
        <td>239 SEK</td>
        <td>$22.92</td>
    </tr>
    <tr>
        <td>Extra PSU</td>
        <td>Free in the recycling bin</td>
        <td>$0</td>
    </tr>
    <tr>
        <td>Network card</td>
        <td>£5 GBP</td>
        <td>$6.04</td>
    </tr>
</table>

<p><strong>Final cost: $81.12 USD</strong></p>

<p>As for results of the tests, and scores:</p>

<table>
    <tr>
        <th>Item</th>
        <th>Output</th>
        <th>Score</th>
    </tr>
    <tr>
        <td>Unigine Sanctuary</td>
        <td><a href="/assets/postimg/cheap_pc_challenge_2022/unigine_20221222_1325.html">325</a></td>
        <td>32.5</td>
    </tr>
    <tr>
        <td>Cinebench</td>
        <td><a href="/assets/postimg/cheap_pc_challenge_2022/11_529_CB25720demo_4C_4T_3400__Intel_Core_i5_3570_CPU__Intel_Intel_R__HD_Graphics_2500_4_0_0___Build_10_18_10_5161_64_Bit.txt">1.562701 single core, 5.925838 multi core</a></td>
        <td>74.88539</td>
    </tr>
    <tr>
        <td>Google Docs</td>
        <td>Average rounded to 4 (3.65, 3.01, 4.21 - but manual timing is inaccurate)</td>
        <td>56</td>
    </tr>
    <tr>
        <td>Price</td>
        <td>$81.12</td>
        <td>18.88</td>
    </tr>
</table>

<p><strong>Final score: 182.26539</strong></p>

<h1 id="retrospective">Retrospective</h1>

<p>So, all in all, a fun thing to do, but christ, what a mess. I really wish I had the time to put that GPU in this, or even just run a single PSU, but that would necessitate a lot of splicing, since my dumpster PSU doesn't have a GPU power connector either. It would've been way easier if I didn't start 22 days late, or lost more than a week to COVID.</p>

<p>Starting late also basically barred me from buying things used internationally, because I couldn't wait a week for things to arrive until I had a basic system actually working. Not being able to wait meant I ended up paying essentially double for the RAM, for example.</p>

<p>I also probably wouldn't take a computer of unknown condition either to start with, but if I did, I would make sure to order enough spare parts to begin with to be able to just replace things if I can't fix them. That bent pin was <em>really</em> close to killing this whole project.</p>

<p>I'd love to see this return for next year - my one critique is probably that the Google Docs test is really finnicky, relying entirely on manual timing. I also wish there was a grace period for the builds, having a cut off date for ordering parts a couple days before the end of the year, but giving up to mid-January for them to arrive, just so your build doesn't get busted by things like the postal service being slow, or sellers not shipping out on time. The spirit of this is throwing together a powerful machine on the cheap in a limited time frame after all - and it sucks when you risk getting disqualified because of something out of your control.</p>

<p>I definitely plan on finishing this up sometime next year - I need to do something about the GPU, which involves making a custom fan duct, and also replacing the PSU, which, well, I probably want to do anyways. Might port coreboot to it, so I can more easily do UEFI crimes.</p>

<h1 id="wait-what-about-the-most-ridiculous-thing-it-can-do">Wait, what about "the most ridiculous thing it can do"?</h1>

<p>We're talking about a $14 computer that running with two separate PSUs at the same time, which sparks unless you connect both of them at the same time, missing a component from the motherboard, with a BIOS flashed that makes it reboot three times before starting. The fact that it runs is already pretty ridiculous.</p>

<p>That being said, I did try to get VR running on it, but the DisplayPort on the integrated graphics doesn't support monitors over 1080p. I ended up playing games for two hours on it by accident though! That integrated GPU isn't the best, but it sure can handle 720p Low, as long as your game doesn't need Vulkan or DX12, which the drivers are too old for.</p>]]></content><author><name>Dusty</name></author><summary type="html"><![CDATA[As I'm writing this, I've just finished with the scoring benchmarks for my entry to Shyra's #CheapPCChallenge2022. I decided to go for something a bit extreme - taking the word cheap to the next level - and plenty of spanners were thrown in the works along the way. I'm surprised I got it as far as I got it!]]></summary></entry><entry><title type="html">My Rimworld Mod Recommendations</title><link href="https://chcl.se/2022/02/18/rimworld-mods.html" rel="alternate" type="text/html" title="My Rimworld Mod Recommendations" /><published>2022-02-18T16:46:00+00:00</published><updated>2022-02-18T16:46:00+00:00</updated><id>https://chcl.se/2022/02/18/rimworld-mods</id><content type="html" xml:base="https://chcl.se/2022/02/18/rimworld-mods.html"><![CDATA[<p>Thought I should compile a list of mods I recommend for <a href="https://store.steampowered.com/app/294100/RimWorld/">RimWorld</a>. Unless otherwise noted, these are all compatible with version 1.3 of the game.</p>

<h2 id="vital">Vital</h2>
<p>I consider these mods pretty non-intrusive and vital - they are all either worth starting a new save over, or can be added to existing ones.</p>

<h3 id="medical-tab">Medical Tab</h3>
<p><a href="https://steamcommunity.com/sharedfiles/filedetails/?id=715565817">Steam Workshop</a></p>

<p>Gives you a quick overview of how your colony is doing medical-wise. Purely UI, so can be added and removed at will.</p>

<h3 id="allow-tool">Allow Tool</h3>
<p><a href="https://steamcommunity.com/sharedfiles/filedetails/?id=761421485">Steam Workshop</a></p>

<p>Adds a bunch of tools that allows you to quickly harvest/haul/allow/forbid parts of the map. It's an essential mod to me, I use the tools all the time.</p>

<h3 id="smart-medicine">Smart Medicine</h3>
<p><a href="https://steamcommunity.com/sharedfiles/filedetails/?id=1309994319">Steam Workshop</a></p>

<p>Fixes a ton of issues with doctoring in the base game (basically just "always using the same medicine type for everything" since 1.3) so you can reserve your glitterworld meds for infections and surgery.</p>

<h3 id="hugslib">HugsLib</h3>
<p><a href="https://steamcommunity.com/sharedfiles/filedetails/?id=818773962">Steam Workshop</a></p>

<p>Required by other mods mostly, but the ability to hit Ctrl+F12 to upload your logs and mod list is a godsend for getting help when troubleshooting.</p>

<h3 id="cm-color-coded-mood-bar">CM Color Coded Mood Bar</h3>
<p><a href="https://steamcommunity.com/sharedfiles/filedetails/?id=2006605356">Steam Workshop</a></p>

<p>Purely UI, gives you a better overview of how pawns are doing at the top of the screen.</p>

<h3 id="rimhud">RimHUD</h3>
<p><a href="https://steamcommunity.com/sharedfiles/filedetails/?id=1508850027">Steam Workshop</a></p>

<p>Purely UI, gives you a much better panel when you select a colonist that lets you see their skills at a glance, etc.</p>

<h3 id="less-arbitrary-surgery-continued">Less Arbitrary Surgery (Continued)</h3>
<p><a href="https://steamcommunity.com/sharedfiles/filedetails/?id=2018250654">Steam Workshop</a></p>

<p>Changes how surgery is calculated to be more based on skill and less reliant on RNG. Your region leading master surgeon will no longer rip off someone's arm when trying to install a wooden hand. Death is part of the game, but I'd much rather have my colonists die in a better way than a bad dice roll.</p>

<h3 id="interaction-bubbles">Interaction Bubbles</h3>
<p><a href="https://steamcommunity.com/sharedfiles/filedetails/?id=1516158345">Steam Workshop</a></p>

<p>Purely UI, shows bubbles when pawns talk to each other. Makes things feel more alive.</p>

<h2 id="nice-to-have">Nice to have</h2>
<p>These mods I consider nice to have, but might change too much for some people. These can still be added in the middle of a run.</p>

<h3 id="clean-pathfinding">Clean Pathfinding</h3>
<p><a href="https://steamcommunity.com/sharedfiles/filedetails/?id=2603765747">Steam Workshop</a></p>

<p>Tosses in some small adjustments into the pathfinding algorithm to make pawns prefer paths that don't generate dirt. Saves <em>so much sweeping</em>.</p>

<h3 id="a-dog-said-animal-prosthetics">A Dog Said... Animal Prosthetics</h3>
<p><a href="https://steamcommunity.com/sharedfiles/filedetails/?id=746425621">Steam Workshop</a></p>

<p>Adds prosthetics for animals, so you don't need to put them down the moment they lose a leg. You know you want it.</p>

<h3 id="set-up-camp">Set Up Camp</h3>
<p><a href="https://steamcommunity.com/sharedfiles/filedetails/?id=1470065926">Steam Workshop</a></p>

<p>Lets your caravans, well, set up camp. Means you can set up a small temporary shack if someone gets sick on the road, has saved my colonists' lives many times.</p>

<h3 id="defensive-positions">Defensive Positions</h3>
<p><a href="https://steamcommunity.com/sharedfiles/filedetails/?id=761219125">Steam Workshop</a></p>

<p>Basically lets you preset where people should go when drafted, so you don't have to set up your colonists manually every single time a raid shows up.</p>

<h3 id="safely-hidden-away">Safely Hidden Away</h3>
<p><a href="https://steamcommunity.com/sharedfiles/filedetails/?id=1322196379">Steam Workshop</a></p>

<p>Adds a reason to potentially settle a longer distance away from others, because it doesn't make sense that a raid party shows up every 5 days if it takes 8 days to travel.</p>

<h3 id="prisoners-should-fear-turrets">Prisoners Should Fear Turrets</h3>
<p><a href="https://steamcommunity.com/sharedfiles/filedetails/?id=2602436826">Steam Workshop</a></p>

<p>Turrets will now shoot escaping prisoners, and oppress slaves.</p>

<h3 id="prisoners-dont-have-keys">Prisoners Dont Have Keys</h3>
<p><a href="https://steamcommunity.com/sharedfiles/filedetails/?id=2595360307">Steam Workshop</a></p>

<p>Like it says on the tin, prisoners don't have keys and need to tear down doors to make it out.</p>

<h3 id="permeable-terrain">Permeable Terrain</h3>
<p><a href="https://steamcommunity.com/sharedfiles/filedetails/?id=2629981384">Steam Workshop</a></p>

<p>Makes it so "liquidy" filth disappears quicker on terrain such as sand, where it otherwise doesn't rain away.</p>

<h3 id="roads-of-the-rim-continued">Roads of the Rim (Continued)</h3>
<p><a href="https://steamcommunity.com/sharedfiles/filedetails/?id=2280318231">Steam Workshop</a></p>

<p>Lets you build roads on the world map. Takes a lot of work, but makes longer caravan trips more viable.</p>

<h2 id="my-mods">My Mods</h2>
<p>Gotta plug my own stuff, I made it for a reason after all :)</p>

<h3 id="robot-vacuum-11-only">Robot Vacuum (1.1 only)</h3>
<p><a href="https://github.com/ChlorideCull/RimworldRobotVacuum">GitHub</a> or <a href="https://steamcommunity.com/sharedfiles/filedetails/?id=2018883927">Steam Workshop</a></p>

<p>Adds a robot vacuum you can build that sweeps the place. Probably going to rework this for 1.3 some time in the future - Ideology added a bunch of stuff this can use to ease development and maintainence.</p>

<p>Has some fun bugs - for example you can end up being chased by manhunter vacuums.</p>]]></content><author><name>Dusty</name></author><summary type="html"><![CDATA[Thought I should compile a list of mods I recommend for RimWorld. Unless otherwise noted, these are all compatible with version 1.3 of the game.]]></summary></entry><entry><title type="html">Chronicles in Reverse Engineering: Gumroad</title><link href="https://chcl.se/2021/07/06/reverse-engineering-chronicles-gumroad.html" rel="alternate" type="text/html" title="Chronicles in Reverse Engineering: Gumroad" /><published>2021-07-06T15:03:00+00:00</published><updated>2024-10-16T20:08:00+00:00</updated><id>https://chcl.se/2021/07/06/reverse-engineering-chronicles-gumroad</id><content type="html" xml:base="https://chcl.se/2021/07/06/reverse-engineering-chronicles-gumroad.html"><![CDATA[<p><em>Update 2022-02: They've added automatic zip downloads some time since I wrote this.</em> <br />
<em>Update 2024-10: Guess what? They've removed it again. Time to dig out the code, I suppose.</em></p>

<p><em>This will be the first of a small series of posts on reverse engineering software and hardware.</em></p>

<p>I recently bought a thing on Gumroad. I quickly realized that said thing was uploaded as 391 items, and unless I did something, I'd be forced to hit Download and then Save on each and every one of them individually.</p>

<p><img src="/assets/postimg/firefox_GQkt5HJyVj.png" alt="Firefox developer console showing 391 child items under &quot;product files&quot;." /></p>

<p>All projects start with a problem that you need to solve, and I really don't want to hit Download and Save for four hours straight.</p>

<h2 id="first-approach">First approach</h2>

<p>The first approach is always the simplest. Hit F12 to open the developer tools in your browser, open the Network tab and refresh the page. See if there's any request you could use - these days there's usually a bunch of JavaScript in the frontend that hits an API. An API is always the first stop - it's designed for computers to make sense of, and it's designed to not require human intervention to use.</p>

<p>The product page didn't have an API, and the purchases page had an API that's not usable for what I want - namely to get a list of links to be able to download quickly.</p>

<h2 id="second-approach">Second approach</h2>

<p>The second approach is looking at native clients, which is pretty much guaranteed to be using an API. I downloaded their Android app from <a href="https://apkpure.com/">APKPure</a>, and tossed it into <a href="https://github.com/skylot/jadx">jadx</a>.</p>

<p>In general, if I need to reverse engineer a client, I go for the simplest option - start with apps in interpreted or JIT languages (Android uses Java, some Windows apps uses C#), and only move to apps in native languages (like on iOS) if you must. With Java and C# you can get readable code out of the box, while native languages require you to know some amount of assembly.</p>

<p>In jadx, I can see that the Android app uses a mobile API with standard REST semantics, and authentication is done through an OAuth 2.0 username/password flow. This is great - it's easy to implement yourself. All you need to do is grab the tokens from the app.</p>

<h2 id="engineering">Engineering</h2>

<p>Reverse Engineering rarely come without some engineering in the end to actually put what you've figured out to use. In this case, because it's largely standards based, I can just use RestSharp to throw together something quickly in .NET 5, with great results.</p>

<p><img src="/assets/postimg/Z69EtPYyWq.png" alt="Terminal showing all 391 files being downloaded through aria2c" /></p>

<p>I'll publish the code once I finish up the auth flow and make it usable without manually looking at API requests.</p>]]></content><author><name>Dusty</name></author><summary type="html"><![CDATA[Update 2022-02: They've added automatic zip downloads some time since I wrote this. Update 2024-10: Guess what? They've removed it again. Time to dig out the code, I suppose.]]></summary></entry><entry><title type="html">Back to Web 1.0</title><link href="https://chcl.se/2020/10/20/web-one-point-oh.html" rel="alternate" type="text/html" title="Back to Web 1.0" /><published>2020-10-20T15:47:00+00:00</published><updated>2020-10-20T15:47:00+00:00</updated><id>https://chcl.se/2020/10/20/web-one-point-oh</id><content type="html" xml:base="https://chcl.se/2020/10/20/web-one-point-oh.html"><![CDATA[<p>I've decided to make this place objectively more fun, and less sterile.
Here's a side by side comparison, for funsies - you can click them to open the screenshots in fullscreen.</p>

<div><a href="/assets/postimg/firefox_tuKZu8k9JV.png"><img src="/assets/postimg/firefox_tuKZu8k9JV.png" style="width:250px" alt="boring, plain old minima design" /></a><a href="/assets/postimg/firefox_VuTXD3FxVp.png"><img src="/assets/postimg/firefox_VuTXD3FxVp.png" style="width:250px" alt="custom design with gifs and pretty colors" /></a></div>

<p>Let me know if you find any accessibility issues, you have my contact details on the home page. Things I know of right now, that's on the to do list:</p>
<ul>
  <li>Skip to content shortcut</li>
  <li>Disabling GIFs if there's a "reduced animation" hint</li>
</ul>]]></content><author><name>Dusty</name></author><summary type="html"><![CDATA[I've decided to make this place objectively more fun, and less sterile. Here's a side by side comparison, for funsies - you can click them to open the screenshots in fullscreen.]]></summary></entry><entry><title type="html">Important Message</title><link href="https://chcl.se/2020/06/27/important-notice.html" rel="alternate" type="text/html" title="Important Message" /><published>2020-06-27T19:56:00+00:00</published><updated>2020-06-27T19:56:00+00:00</updated><id>https://chcl.se/2020/06/27/important-notice</id><content type="html" xml:base="https://chcl.se/2020/06/27/important-notice.html"><![CDATA[<p><img src="/assets/chloridecull_bitassembly.gif" alt="Chloride waving a flag" /></p>

<p>That is all. Kudos to <a href="https://twitter.com/BitAssembly">Bit Assembly on Twitter</a> for making the artwork.</p>]]></content><author><name>Dusty</name></author><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Oh look, a blog</title><link href="https://chcl.se/2020/05/05/blag.html" rel="alternate" type="text/html" title="Oh look, a blog" /><published>2020-05-05T17:54:00+00:00</published><updated>2020-05-05T17:54:00+00:00</updated><id>https://chcl.se/2020/05/05/blag</id><content type="html" xml:base="https://chcl.se/2020/05/05/blag.html"><![CDATA[<p>Thought this would be better than the old single page with an image. Need some place for longer technical stuff, I suppose.</p>

<p>Go look at my Twitter instead. It's more exciting.</p>]]></content><author><name>Dusty</name></author><summary type="html"><![CDATA[Thought this would be better than the old single page with an image. Need some place for longer technical stuff, I suppose.]]></summary></entry></feed>