top of page

Break Me: The Movfuscator – Turning mov into a Soul-Crushing RE Nightmare

Updated: Jul 16


Hello everyone, I want to talk about something that started as a bit of a humorous observation but quickly evolved into a fascinating, and frankly, terrifying, anti-reverse engineering concept: the Movfuscator. It all began with Steven Dolan's insightful, and somewhat cheeky, assertion that the x86 mov instruction alone is Turing complete. That's right – theoretically, you can write any program using only mov instructions.



The mov-Only Challenge: A Reverse Engineer's Worst Nightmare


Think about what reverse engineering typically involves: disassembling executables, analyzing instruction types, and mapping out control flow graphs (CFGs) to understand program logic. We look for add, sub, jmp, call – instructions that give us clues about what the code is doing.

But what if all you saw were mov instructions? Just endless streams of data transfers. No obvious arithmetic, no explicit branches, no function calls. It would be an indecipherable mess, a flat, linear sequence of operations that would make traditional reverse engineering tools and techniques utterly useless. This is the core idea behind the Movfuscator: to simplify programs to the point of extreme obfuscation, making every program look identical – a soul-crushing stream of mov operations.



Building Blocks for a mov-Only World


To prove Dolan's assertion and build a practical mov-only compiler, I had to figure out how to implement higher-level programming constructs using only mov.

  • Equality Check: Dolan's original idea for an equality check was ingenious. By writing a 0 and a 1 to specific memory locations and then performing a mov operation that would result in a different value being written based on equality, you could infer if two values were the same.

  • Conditional Execution: Since explicit branches are forbidden, conditional execution is achieved by routing operations to either real data or "dummy data." If a condition isn't met, the mov instructions operate on dummy memory, effectively having no impact on the program's actual state.

  • Looping and Halting: Dolan's original Turing machine relied on a single jmp instruction for looping and an invalid memory address for halting. For the Movfuscator, I later found a way to eliminate the final jmp by making the program its own illegal signal exception handler. An illegal mov instruction would then trigger an exception, causing the program to loop back to a desired point.



Implementing Higher-Level Logic


Translating high-level constructs into mov-only operations required some creative thinking:

  • If Statements: These are implemented using "selector functions," which are essentially arrays of pointers. Based on a condition, a mov instruction would select either a pointer to the real operation or a pointer to a no-op (dummy data operation).

  • Branches and Loops: These are simulated by effectively "turning off" execution. When a branch or loop condition is met, all subsequent mov operations are directed to dummy data until the program counter reaches the target address. At that point, execution is "turned on" again, directing mov operations to real data.

  • Arithmetic and Logic Gates: For byte-sized data, these are implemented using extensive lookup tables. Operations like increment, decrement, AND, and OR become simple memory lookups, where the input values are used as an index into a precomputed table of results. This can be cascaded for 32-bit operations.



The Movfuscator in Action: From Brainf**k to C


My first step was to build a mov-only compiler for Brainf**k, a minimalistic esoteric programming language. This proved the concept, as each Brainf**k instruction could be translated into a series of mov operations using the macros I developed. I also tackled the int 80 (system call) issue by leveraging memory-mapped I/O, eliminating the need for any non-mov instructions for basic input/output.

The real challenge, and the true nightmare for reverse engineers, came with Movfuscator 2.0: a full C compiler that outputs only mov instructions. This involved:

  • Implementing 32-bit arithmetic (addition, subtraction, multiplication, division) using cascades of 8-bit lookup table operations.

  • Creating an emulated stack entirely with mov operations.

  • Defining a completely new calling convention that relies solely on data movement.

The results were astonishing. I demonstrated a playable Nibbles game compiled entirely with mov instructions. I even implemented a mov-only floating-point emulator to enable 3D graphics, showcasing a spinning cube – all rendered through nothing but movs!



The Anti-Reverse Engineering Impact


The implications for anti-reverse engineering are profound:

  • Annihilation of CFGs: Movfuscated programs appear as a single, massive basic block. All control flow is gone, making traditional CFG analysis useless.

  • Tool Crashing: Common reverse engineering tools like IDA Pro often crash or struggle immensely when faced with such enormous single blocks of instructions.

  • Uniformity: Every program, regardless of its original complexity, looks the same – a flat, featureless landscape of mov instructions. This prevents pattern recognition and makes it incredibly difficult to differentiate between benign and malicious code.

  • Further Obfuscation: Techniques like instruction shuffling, inserting junk movs, and interleaving blocks can be applied to further obscure the original program logic, making any attempt at analysis a truly "soul-crushing" experience.



Beyond mov: The Future of Blankfuscators

The mov instruction is just one example. I've also explored other Turing-complete instructions that could form the basis of similar "blankfuscators," including xor, and/or, sub, cmpxchg/xchg, and even single-bit shifts. The ultimate goal? A C compiler that outputs no instructions at all, leveraging the x86 memory management unit itself, which has been shown to be Turing complete.

While the Movfuscator might not be a "legitimate" anti-reverse engineering solution in the traditional sense, it's a powerful demonstration of what's possible when you think outside the box. It was an incredibly fun, challenging, and eye-opening project, and all the source code, other "blankfuscators," and even a crackme challenge are available on my GitHub. Go ahead, try to break it!


Christopher Domas (@xoreaxeaxeax)


Materials

Recent Posts

See All
bottom of page