Recent Posts

Writeups for Dennis Yurichev's Reverse Engineering Challenges (#12-#22)

May 28, 2019

This is the second set of solutions for my self-imposed challenge of completing at least fifty of the exercises on Dennis Yurichev's challenges.re by the end of the year. The first set is available here.

read more ➔

Transitioning to Haunt

May 04, 2019

Rather than study for finals this week, I spent my time moving this blog over to Haunt. Previously, I was using Hugo, and while ox-hugo made the authoring workflow tolerable, doing anything on the rendering side of things was unsavory at best. I eventually had enough and decided to look for another solution, of which Haunt was the most enticing.

read more ➔

Writeups for PlaidCTF 2019

April 14, 2019

My long-lived hiatus from capture-the-flag has come to an end, as I got off my ass this weekend to play in PlaidCTF 2019. Being a one-man team is pretty lonely, but my old team wasn't playing, and even if they were, I don't know if I would've wanted to make the commute just to play with them.

read more ➔

Writeups for Dennis Yurichev's Reverse Engineering Challenges (#2-#11)

March 10, 2019

As mentioned in the post I wrote describing my plans for 2019, one of my goals this year is to get through at least 50 of the exercises on Dennis Yurichev's challenges.re. I've decided to document my progress in the form of writeups for the challenges I complete, batched in sets of ten exercises. For each challenge, I'll try to explain the intuitions that brought me closer to answering the recurring question from Yurichev, "[w]hat does this code do?"

read more ➔

A Reflection on "New Ambitions for a New Year"

March 03, 2019

On the night of December 31st of last year, I wrote "New Ambitions for a New Year," a blog post outlining a number of self-imposed goals for 2019. The words I ended on were: "[t]oo ambitious? Well, I guess we'll find out in 365 days when I write another post like this." Indeed, what you're reading right now is something I expected to author much later, but enough has changed in the past three months that I feel it's appropriate to put out an addendum now. The post's original text follows.

read more ➔

First Impressions of the Kotlin Programming Language

December 17, 2018

In the introduction of the previous post I wrote for this series, First Impressions of the Rust Programming Language, I alluded to the presence of arguments that programming language safety should be achieved by moving to languages such as Java which run on a virtual machine. While "safety" may no longer be the first thing that comes to mind in discussion of these languages, especially with the hundreds1 of vulnerabilities in various implementations of the Java virtual machine, it would be unfair to deny that the principle of running programs in a sandboxed virtual machine is safer than running machine code directly. This post won't be making any claims about safety, though, as I'm more interested in writing about my impressions from a language design perspective. So, how does Java fare in this regard?

read more ➔

Slime the World: A Postmortem

November 02, 2018

Slime the World was my entry to this year's Autumn Lisp Game Jam, and it managed to win second place. The theme was slime, so it’s a game about covering everything in sight with slime, and the dialect of Lisp I chose to use was Fennel, a simple and elegant Lisp that I feel perfectly matches the simplicity and elegance of Lua. It takes on a more "modern" style that I associate with Lisps such as Clojure. I had initially pushed Clojure to the side, feeling it was too different from Common Lisp, but now that I've had a positive firsthand experience with a Lisp where lists aren't the data structure you always reach for, I'm hoping to return to it with an open mind.

read more ➔

First Impressions of the Rust Programming Language

June 08, 2018

C is almost 50 years old, and C++ is almost 40 years old. While age is usually indicative of mature implementations with decades of optimization under their belts, it also means that the language's feature set is mostly devoid of modern advancements in programming language design. For that reason, you see a great deal of encouragement nowadays to move to newer languages - they're designed with contemporary platforms in mind, rather than working within the limitations of platforms like the PDP-11. Among said "new languages" are Zig, Myrddin, Go, Nim, D, Rust… even languages like Java and Elixir that run on a virtual machine are occasionally suggested as alternatives to the AOT-compiled C and C++.

read more ➔

Installing Gentoo: One Month Later

May 28, 2018

It seems that the general consensus on "distro hopping," the act of constantly switching between distributions of GNU/Linux, is that it's a bad habit that should be consciously avoided. If you do a search for the term, you'll get articles with titles along the lines of "How I Stopped Distro Hopping." But it's also a term that gets thrown around loosely, and I think that that "distro hopping" is an acceptable practice in a lot of the contexts where the phrase is used. Needless to say, I've "hopped" distributions in the past month, and this blog post is going to describe the highs and lows of that experience.

read more ➔

Reverse Engineering By Hand

March 01, 2018

My capture-the-flag team played in the Insomni'hack teaser this year. During the competition, I worked on a single challenge titled "sapeloshop." It was labeled as "Medium-Hard," and it was in the binary exploitation category. The source code for the server wasn't provided, so reverse engineering was necessary. I don't think that having to reverse the binary was supposed to be the hard part, as most of the behavior could have been inferred through some high-level analysis, yet I spent nearly five hours fruitlessly trying to reverse it, and the subsequent burnout was bad enough that I went home early. This wasn't the first time a reversing task had gotten the best of me; there had been a few competitions last year where I felt a similar loss in motivation. Noticing this recurring pattern frustrated me, and that frustration drove me to think about ways to improve myself as a reverse engineer.

read more ➔

Duke on Fluidsynth

January 13, 2018

My first experiences with Duke Nukem 3D were with EDuke32 ages ago. This was back when I was running Windows Vista, and while my memory is a bit lacking, I swear that I had working music then. Ever since I made the switch to Linux, I haven't had working music playback in EDuke. Frustrated at the fact that my past few years of Duke 3D have been devoid of all sound besides the screams of death and Duke's trash talking, I've finally decided to troubleshoot it.

read more ➔

Bad BEHAVIOR

January 04, 2018

TL;DR, I discovered a stack-smashing vulnerability in GZDoom's interpreter for ACS. As a preface, there's a tendency for whitepapers like this in the security community to be written with a somewhat condescending tone towards the product's vendor. I do not mean for any portion of this writeup to come off as degrading to the developers involved. Yes, the bug was obvious to me, but it was still subtle enough that it went under the radar for nearly 23 years. Most developers aren't actively thinking about this kind of attack while writing a bytecode interpreter. I have an enormous amount of respect for the development teams of both GZDoom and Zandronum, who were quick to issue a patch addressing the issue and were respectful of my wishes to release this whitepaper to the public. I'd also like to thank everyone I had the pleasure of working with during this process; it warms my heart to know that the communities behind these open-source software projects are this friendly.

read more ➔

BackdoorCTF 2017: FUNSIGNALS

September 24, 2017

"funsignals" was a 250 point binary exploitation challenge with 58 solves. The challenge itself was a very trivial example of sigreturn-oriented programming.

read more ➔

Understand Game Hacking In One Post

September 05, 2017

At a first glance, it might seem that game cheats like AimTux are something that could only be conjured by the most talented of reverse engineers. That was at least my initial view on it, especially since I always saw these game hackers using outlandish terms that I hadn't heard in over a year of playing in CTF's. Don't be fooled; game hacking isn't nearly as complex as its community makes it seem. In this post, I will explain the concepts in a way that is familiar to people with experience in binary exploitation and reverse engineering, but it shouldn't be too hard to understand if you lack that background.

read more ➔

Analyzing Executable Size, part 0 - A Small Proof-of-Concept Loader

July 31, 2017

It seems that static linking is back in style, or at least popular among all the hip new programming languages of today. I don't have anything against statically linked binaries, nor do I have a problem with larger executables, but I've noticed that the acceptable size for an executable is a lot larger now than it was a few years ago; that is, the new kids on the block have significantly more leeway than their predecessors. For example - a C program that spits out "hello world" is 7 KB when statically linked to musl. It's 12 KB when dynamically linked to glibc. The same program in D, where the reference compiler doesn't allow dynamic linking to the standard library, is 896 KB. A blog post I read recently about certificate chain verification in Go made a point of praising the toolchain for being able to spit out a binary that was "less than 6 MB!" I'm being more facetious than with my D example, as this was statically linked to an SSL-capable web server, but 6 MB is a little over half the size of a fully-functioning operating system. I'm not so interested in why we settle binaries the size of a few videos, but instead I'd like to look at why they're that large to begin with. To peer in and see what wealth of information is stored inside, and how certain programming languages make use of that information.

read more ➔

Making Your Own Music Player: A Gentle Introduction to Audio Programming

July 15, 2017

To start off, I'd like to say that I know very little about audio programming and digital audio in general. I've never formally studied signal processing, and hell, I haven't even started high school physics yet. This post merely documents what I've learned while trying to get sound working in my game, because there aren't really any other learning resources about this out there.

read more ➔

Reverse Engineering Babby's First Archive Format

March 02, 2017

About two months have passed since the first release of Nekopack - a tool I wrote for extracting game data from Nekopara's XP3 archives. While the process wasn't an amazing reverse-engineering war story that will keep you on the edge of your seat, I feel it deserves a small blog post explaining how I did it. Additionally, there's no real documentation on the XP3 format as far as I'm aware, so hopefully this post will serve as an informal specification.

read more ➔

SDL Tutorial Part 0x00 - Boilerplate, Windowing and Rendering

September 14, 2016

This is one of my older tutorials and follows a style unlike my current one. I also no longer hold the same claims I made about the SDL documentation that I originally made in this article. I think it's perfectly fine, you just need to spend some time looking around because it's not organized like other documentation is. For that reason, I have no plans to continue this tutorial series unless someone specifically asks for me to continue it.

read more ➔