4 ms·
I've been reverse-engineering the 8086 lately, and I recently came across the exact register-control circuitry that makes this steganography possible. The steg
by kens 6y ago
I've been reverse-engineering the 8086 lately, and I recently came across the exact register-control circuitry that makes this steganography possible.
The steganography takes advantage of x86 instructions where you can swap the source and destination by replacing an instruction like hex 31 c0 with 33 c0. The difference is bit 1, the direction bit, supported by many instructions.
Internally, the 8086 has 5-bit registers that specify the source and destination, typically a register. [1] The source and destination register get their value either from the register specification in the instruction (bits 5-3 or bits 0-2), or values in the microcode.
The clever part is the outputs of the source and destination registers go through multiplexers that can swap them. If the instruction has a direction bit, and the direction bit is set, then accesses to the source and destination registers are swapped.
The point of this is that the microcode doesn't know anything about direction swapping, so it is implemented "for free" as far as microcode size (but with the addition of the swapping circuit).
The 8086 has a "Group PLA" that categorizes instructions into groups; one of these groups is "instructions that have a direction bit". This prevents direction swapping from happening for instructions where it is not supported.
I hope this explanation makes sense; it should probably be a blog post :-)
[1] You might wonder why source and destination are specified with 5 bits when the instructions use 3 bits to specify the register. The first reason is that many registers can be accessed as half-registers, so you need another bit. (This bit comes from the byte/word specification bit in instructions.) Second, this mechanism is used to access the other 8086 registers, not just the general-purpose registers. Third, there are also invisible temporary registers that also need accessing. Thus, the internal register specifications are 5 bits.
- woodruffw 6y agoThis is a fantastic explanation, thank you! I would love a detailed blog post on it.
- drudru11 6y agoThanks for writing this up Ken. Strangely enough, I was researching a related topic a few days ago. I was wondering if disassemblers did the right thing with these opcodes. I was wondering in particular if they could reproduce the exact binary after disassembly. It turns out that most assemblers do not have a specific way to make a distinction. The gnu assembler (gas) does have a ‘.s’ suffix for mnemonics to differentiate.
- anyfoo 6y agoBy the way, since you asked what people would like reading about the 8086, I would greatly enjoy an article focusing on its microcode, both what it implements and how it's processed (not necessarily in one article).