Even the cheap LLMs are great in doing the awful crud work in the beginning: finding offsets, firmware update file structures, brute forcing checksums, etc.
It still produces a lot of crap in the later steps (understanding the implementation itself) but I'm happy doing this stuff myself then.
I've had success here by adding a phase called "grounding" that attempts to verify its "understanding" by creating tests that modify the running executable to ensure its made the right inference.
Is this variable really MARIO_X? Change it and see if Mario moves. Etc.
As an example in Donkey Kong - the system had trouble deciding if an array controlled barrels or fireballs. There was conflicting evidence.
After many trips through the loop - it realized it does BOTH, depending on which level you're on.
So the "understanding" grows with each iteration.
In Time Pilot - there are three routines that are called constantly from inside the main loop. Each routine computes the checksum of the other routine's code to see if it's been modified. If so it jumps into random junk data.
There are other less exotic routines that make sure the copyright string hasn't been modified, etc.
https://github.com/qarl/arcade-js/blob/main/games/timeplt/id...
Fascinating.