Hello everyone, it's been a while since my last post, and today we're going to fix that.


Our story began with a message from my friend-reverser colby57: "The first time I saw this, I thought I was about to crash, but everything was valid". The attachment was a shell sample. Nothing special at first glance, but in the middle of the code, the disassembler simply broke off, showing "garbage" bytes further on. The processor, however, executed this code without any issues.

This "garbage" turned out to be two opcodes: 0F 1A and 0F 1B. There are actually more of them, but only two will be mentioned.

And this isn't a bug in a specific sample. It's a systemic failure of the entire reverse engineering industry, laid down by an Intel patent almost 30 years ago.

Digging into the past: where did these ghosts come from?

The roots of our problem go back to 1997, to one of Intel's most elegant patents, created at a time when the world was preparing for the Y2K problem. Back then, Intel faced an eternal headache - backward compatibility. Engineers added bunches of cool instructions to new processors, but developers wouldn't touch them, fearing their programs wouldn't run on computers released a couple of years earlier.

1000026070.png

The solution proposed in patent US5,701,442 was brilliantly simple. "What if we reserve an entire range of opcodes - from 0x0F18 to 0x0F1F - as just placeholders?" In the patent, they were called Hintable NOPs.

On processors of that time, they did absolutely nothing. But at any moment, any placeholder could "come alive" and turn into a new, useful instruction. On older computers, such an instruction would execute as a harmless NOP, on newer ones - as a powerful tool.

And so it happened. 0x0F18 turned into the PREFETCH family of instructions, and 0x0F1E after twenty years became the heart of CET protection technology in the form of ENDBR64. Most opcodes from this range were eventually either utilized or, at the very least, correctly recognized by disassemblers.

Except for two. Opcodes 0F 1A and 0F 1B became real ghosts. They remained in the shadows, forgotten by everyone except the silicon itself and the pages of that very patent.

Live test: breaking everything

Enough theory. My good friend wrote a simple PoC binary containing these instructions, and we decided to run it through our pack of standard tools. Let's look at this together.

GitHub repository with PoC

First patient: x64dbg

We load our binary into the debugger. Here they are, our "garbage" bytes. x64dbg honestly shows us ???, unable to recognize the instruction.

1000026064.jpg

The EIP arrow points to the line with bytes 0F 1A C0. In the disassembler column on this line are three question marks.

But the most interesting thing is the processor's behavior. We step (F7), and... EIP calmly jumps over this "unknown" instruction and continues. No crash, no error. For the CPU, it's valid, executable code. For the debugger - some nonsense