vabold

vabold

@vabold.bsky.social

Kinoko developer. https://github.com/vabold/Kinoko

32 followers5 following72 posts

Interesting (and slightly unexpected) development: decompilations have started going private due to counterfeiting. I think this is a relatively recent problem stemmed by people who don't understand decompilation suddenly thinking they can contribute. Be advised, this is a more speculative thread.

View full thread

My speculation is that I expect more will follow suit. Your work can't be counterfeited if it's never publicly worked on. I don't expect Mario Kart Wii to follow suit, because LLMs appear to be poisoned by the partial C documentation in our symbols. Humans know to replace them, LLMs don't.

In other instances where people are unburdened by technical debt, though, I imagine needing to sift through low-quality PRs is tedious (and God forbid the PR is closed and a counterfeit fork is made if someone's spiteful enough).

Interesting (and slightly unexpected) development: decompilations have started going private due to counterfeiting. I think this is a relatively recent problem stemmed by people who don't understand decompilation suddenly thinking they can contribute. Be advised, this is a more speculative thread.

View full thread

We're starting to see websites dedicated to making counterfeit forks. I'm not even going to link this. All this does is encourage decompilation maintainers to go private with development, so as to keep high quality code unstolen while it's being worked on.

Where does that leave us? Metroid Prime 2: Echoes is private. Animal Crossing: City Folk is private. I don't blame any of these maintainers for doing so. Unlisted decomp.dev pages, something that would've been unthinkable before, are implemented.

Interesting (and slightly unexpected) development: decompilations have started going private due to counterfeiting. I think this is a relatively recent problem stemmed by people who don't understand decompilation suddenly thinking they can contribute. Be advised, this is a more speculative thread.

View full thread

Are the pesky humans taking too long at decompilation? Have they banned LLM contributions for whatever reason? No worries! Take all of their progress, fork it, swap out the README to encourage LLM contributions, and simply match the remaining functions with LLMs to 100%.

Unfortunately, people have actually tried this. They've even gone so far as to try to get CI from decomp.dev. This leads to the project being disabled, as it should, but when that fails people just steal the website next. Tthis actually happened with 999: Nine Hours, Nine Persons, Nine Doors.

Interesting (and slightly unexpected) development: decompilations have started going private due to counterfeiting. I think this is a relatively recent problem stemmed by people who don't understand decompilation suddenly thinking they can contribute. Be advised, this is a more speculative thread.

A couple threads back, I talked about how LLMs drift the decompilation process away from reverse engineering. The job of the LLM is to bytematch at all costs. Solutions that would be dismissed under normal circumstances are now being presented by people who don't know any better.

This is normally not a problem when project leads who know better are in control (in this example, this PR was closed almost instantly), but now we're starting to see something that can't easily be swatted away: malicious forks.

For anybody looking for a summary of this 28-post thread:

vabold@vabold.bsky.social

A few days ago, I got to see GPT-6 Astra try its hand at C++ decomp. We used Wii Speak as a proving ground, specifically with one of the first-party libraries called EGG. This is a library I have a lot of knowledge of and can comfortably navigate in Ghidra with zero reverse engineering. How'd it do?

A few days ago, I got to see GPT-6 Astra try its hand at C++ decomp. We used Wii Speak as a proving ground, specifically with one of the first-party libraries called EGG. This is a library I have a lot of knowledge of and can comfortably navigate in Ghidra with zero reverse engineering. How'd it do?

View full thread

To wrap up, here is my takeaway: Astra is passable in initial reverse engineering sweeps and is very capable of decompilation with base knowledge. With the right management, I think it's possible to leverage this to get something high-quality and fast.

HOWEVER, I'm still unconvinced that this is something worth paying money for. Astra is obviously a very high-end model with a major dependency on OpenAI (or Anthropic), and frankly I don't think the money is best spent like this. With focused effort, I think a human still outperforms.

A few days ago, I got to see GPT-6 Astra try its hand at C++ decomp. We used Wii Speak as a proving ground, specifically with one of the first-party libraries called EGG. This is a library I have a lot of knowledge of and can comfortably navigate in Ghidra with zero reverse engineering. How'd it do?

View full thread

Here, we see some misunderstanding of the HBM. Despite these function names all revolving around a "result", two of them correspond to a bitflag and one of them corresponds to a completely separate member. This switch statement is also meant to be of the return type of HBMCalc, an enum for buttons.

That isn't to say this is completely useless for reverse engineering. It found this to mean shutdown, and after cross-referencing Wii Shop Channel for clues, I found this was a function I had labeled a while ago called CNTShutdown.

A few days ago, I got to see GPT-6 Astra try its hand at C++ decomp. We used Wii Speak as a proving ground, specifically with one of the first-party libraries called EGG. This is a library I have a lot of knowledge of and can comfortably navigate in Ghidra with zero reverse engineering. How'd it do?

View full thread

Going back to Astra's work, we see instantiation of this supposed System class that more strikingly resembles EGG::TSystem<>::Configuration. This assuredly is not templated, but this is the job the configuration has, not the system.

It's also misusing the term "configure", having pulled it from the vocabulary seen in the linker map, but not fully understanding its context. In the original library, this is meant to change the static pointer that the system classes have to the configuration data. We're seeing it bastardized here.

A few days ago, I got to see GPT-6 Astra try its hand at C++ decomp. We used Wii Speak as a proving ground, specifically with one of the first-party libraries called EGG. This is a library I have a lot of knowledge of and can comfortably navigate in Ghidra with zero reverse engineering. How'd it do?

View full thread

Big Brain Academy: Wii Degree uses the intended configuration setup. They have a more-or-less stock configuration and YSystem is omnipresent for any code that needs it. Which one of these three best fits Wii Speak? We don't have symbols, so it should be impossible to tell... but it's likely BBA:WD.

When going over scenes, I noticed a very familiar name pop up: Kiuchi. Upon further examination, I found two more familiar names: Kitayama and Masuda. Muraki, Minato, and Kando are absent and seem to be replaced with other developers I don't recognize (Itoy? Oshino? Kida? Kato?)

A few days ago, I got to see GPT-6 Astra try its hand at C++ decomp. We used Wii Speak as a proving ground, specifically with one of the first-party libraries called EGG. This is a library I have a lot of knowledge of and can comfortably navigate in Ghidra with zero reverse engineering. How'd it do?

View full thread

All of the system classes are completely static and call into their respective instances of the ConfigurationData. Game classes sometimes operate the same way, but sometimes don't. Nintendo EAD was a big department, and there were many styles on how to handle this.

Pack Project (Wii Sports, Wii Play, etc) rely on RPSysSystem, which afaict wraps RPSysConfigData. However, it's one of the only system classes that has an instance. Zelda framework (Skyward Sword, New Super Mario Bros Wii) use a static system class called dSys_c, which houses everything statically.

A few days ago, I got to see GPT-6 Astra try its hand at C++ decomp. We used Wii Speak as a proving ground, specifically with one of the first-party libraries called EGG. This is a library I have a lot of knowledge of and can comfortably navigate in Ghidra with zero reverse engineering. How'd it do?

View full thread

Let's take a bit about the normal side of EGG system classes. Everything is accessed from a ConfigurationData interface (which also houses some internal heap members), and all of the externally-provided managers live in a TSystem<>::Configuration instance. TSystem<> and BaseSystem are wrappers.

A few days ago, I got to see GPT-6 Astra try its hand at C++ decomp. We used Wii Speak as a proving ground, specifically with one of the first-party libraries called EGG. This is a library I have a lot of knowledge of and can comfortably navigate in Ghidra with zero reverse engineering. How'd it do?

View full thread

This is the true test. It can't copy any code I've labeled in Ghidra or any code from Wii Sports. It must reverse engineer everything and decompile everything itself from here. It has a base to work with in the form of the original EGG system code. What can it do here?

Takeaway 2/2: Astra is good at decompiling. Honestly. It's actually better than many humans I've seen who work on these kinds of games and fall into the trap of avoiding the omnipresent OOP we know exists. Astra's problems lie instead with the reverse engineering side.

A few days ago, I got to see GPT-6 Astra try its hand at C++ decomp. We used Wii Speak as a proving ground, specifically with one of the first-party libraries called EGG. This is a library I have a lot of knowledge of and can comfortably navigate in Ghidra with zero reverse engineering. How'd it do?

View full thread

Astra isn't using all of the resources it has at its disposal for correct answers. I realize this is likely a different story if we don't give it access to other decomp repositories, but it makes me feel correct in my understanding that LLMs will try to take as many shortcuts as possible.

While trying to manually reverse engineer Wii Speak's system code, I realized that their version of EGG is very heavily modified. The system code lies in between two known EGG TUs, making it an indisputable part of the library. We got bored of watching it copy Wii Sports, so we directed it to this.

A few days ago, I got to see GPT-6 Astra try its hand at C++ decomp. We used Wii Speak as a proving ground, specifically with one of the first-party libraries called EGG. This is a library I have a lot of knowledge of and can comfortably navigate in Ghidra with zero reverse engineering. How'd it do?

View full thread

Because Astra was matching root heap creation functions in the Heap source file, this was an instant red flag that something was up with the system. While it continued work on Thread and TaskThread, I instantly knew something was up with the system classes and went to investigate.

Wii Speak weirdness aside, takeaway 1/2 came from the ColorFader constructor in attached image 1. For context, here's all the information we can glean from the constructor in attached image 2. The TBitFlag<u8> instantiation is missing! This solidified it was copying Wii Sports directly.

A few days ago, I got to see GPT-6 Astra try its hand at C++ decomp. We used Wii Speak as a proving ground, specifically with one of the first-party libraries called EGG. This is a library I have a lot of knowledge of and can comfortably navigate in Ghidra with zero reverse engineering. How'd it do?

View full thread

These are, as far as I can tell, new functions that don't exist in any other program that uses this library. invokeAllocCallback is an easy to understand change, but the root heap creation functions are very strange. The arena heaps are not instantiated like this.

Let's talk about the EGG system. Because EGG overrides operator new to use their heaps, the system has to initialize the heaps first before anything can happen. This is done by making a static configuration and calling a function called initMemory. Here's roughly what it looks like in MKW:

A few days ago, I got to see GPT-6 Astra try its hand at C++ decomp. We used Wii Speak as a proving ground, specifically with one of the first-party libraries called EGG. This is a library I have a lot of knowledge of and can comfortably navigate in Ghidra with zero reverse engineering. How'd it do?

View full thread

One very important thing I nearly forgot: we also gave it my Ghidra project files for EGG which has about 30 DOLs to look from (many are not labeled because I use a small minority).

The first thing it did, predictably, was start working on ExpHeap. This involves Heap, Disposer, and Allocator, so it started on those too. The code itself was nearly identical to the work we've previously done on it (with one fakematch for Heap::dumpAll), but something caught my eye immediately.

A few days ago, I got to see GPT-6 Astra try its hand at C++ decomp. We used Wii Speak as a proving ground, specifically with one of the first-party libraries called EGG. This is a library I have a lot of knowledge of and can comfortably navigate in Ghidra with zero reverse engineering. How'd it do?

View full thread

We have three known link orders from here. One of them is the standard one from Big Brain Academy: Wii Degree. One of them is the subfolder-independent alphabetical order from Mario Kart Wii. The other one is subfolder-dependent alphabetical order from Wii Music.

With the knowledge of how to bootstrap into EGG TUs, and allowing it to cross-reference with existing decomp, we let it loose on EGG to see how it would do. I also gave it other reverse-engineering tricks I use frequently, such as how Big Brain Academy: Wii Degree's linker maps give matching clues.

A few days ago, I got to see GPT-6 Astra try its hand at C++ decomp. We used Wii Speak as a proving ground, specifically with one of the first-party libraries called EGG. This is a library I have a lot of knowledge of and can comfortably navigate in Ghidra with zero reverse engineering. How'd it do?

View full thread

I'll be using the The Legend of Zelda: Skyward Sword Save Data Update Channel as reference because it has this library and I don't think anyone has ever cared to document it. Eventually, you will find this. The 0x45585048 means 'EXPH' in ASCII. This is an SDK function called MEMCreateExpHeapEx.

If we look at the callers, we will eventually stumble upon a function with two more consecutive rlwinm instructions. It will call into it with notable constants 0x38 and 0x3c. This is EGG::ExpHeap::create, and all EGG projects will have this.

A few days ago, I got to see GPT-6 Astra try its hand at C++ decomp. We used Wii Speak as a proving ground, specifically with one of the first-party libraries called EGG. This is a library I have a lot of knowledge of and can comfortably navigate in Ghidra with zero reverse engineering. How'd it do?

It... pretty much just copied everything I knew as context and referenced Wii Sports heavily for implementation. To that end, I'll talk more about what I explained as bootstrap knowledge before we get into one of the more surprising outcomes. First things first, how do we find EGG to start with?

010101.. ........ 00000000 00111010 This is an rlwinm instruction with variable registers to round down to 0x4 alignment. Heap creation works by rounding up the start address and rounding down the end address, so two (near-)consecutive rlwinms generate next to each other.