What is "overlapping instructions" obfuscation? (original) (raw)
It's also known as the 'jump in the middle' trick.
explanation
execution rules
- most instructions take more than one byte to be encoded
- they can take up to 15 bytes on modern CPUs
- execution can start at any position as long as permissions are valid
so any byte following the first one of an instruction can be re-used to start another instruction.
abusing disassemblers
- straighforward disassemblers start the next instruction right after the end of the last one.
so such disassemblers (that don't follow the flow) will hide the instruction that is in the middle of a visible one.
examples
trivial
00: EB 01 jmp 3
02: 68 c3 90 90 90 push 0x909090c3
will effectively execute as
00: EB 01 jmp 3
03: C3 retn
...
as the first jmp
skips the first byte 68
(which encodes an immediate push) of the following instruction.
multiple overlaps
from this example, 69 84
defines an imul
instruction that can take up to 11 bytes. Thus you can fit several lines of instruction in its 'fake' operands.
00: EB02 jmp 4
02: 69846A40682C104000EB02 imul eax, [edx + ebp*2 + 0102C6840], 0x002EB0040
0D: ....
will actually be executed as
00: EB02 jmp 4
04: 6A40 push 040
06: 682C104000 push 0x40102C
0B: EB02 jmp 0xF
0F: ...
instruction overlapping itself
The instruction is jumping in the 2nd byte of itself:
00: EBFF jmp 1
02: C0C300 rol bl, 0
will actually be executed as
00: EBFF jmp 1
01: FFC0 inc eax
03: C3 retn
different CPU modes
this obfuscation can be extended to jumping to the same EIP but in different CPU mode:
- 64b CPUs still supports 32b instruction
- 64b mode is using
0x33
forcs
- some instructions are available only in a particular mode:
arpl
in 32b modemovsxd
in 64b mode
so you can jump to the same EIP
but with a different CS
, and get different instructions.
In this example, this code is first executed in 32b mode:
00: 63D8 arpl ax,bx
02: 48 dec eax
03: 01C0 add eax,eax
05: CB retf
and then re-executed in 64 bit mode as:
00: 63D8 movsxd rbx,eax
02: 4801C0 add rax,rax
05: CB retf
In this case, the instructions are overlapping, not because of a different EIP, but because the CPU temporarily changed from 32b to 64b mode.