CHAPTER 50. OBFUSCATION CHAPTER 50. OBFUSCATION
50.2 Executable code
50.2.1 Inserting garbage
Executable code obfuscation implies inserting random garbage code between real one, which executes but does nothing
useful.
A simple example:
Listing 50.1: original code
add eax, ebx
mul ecx
Listing 50.2: obfuscated code
xor esi, 011223344h ; garbage
add esi, eax ; garbage
add eax, ebx
mov edx, eax ; garbage
shl edx, 4 ; garbage
mul ecx
xor esi, ecx ; garbage
Here the garbage code uses registers which are not used in the real code (ESIandEDX). However, the intermediate results
produced by the real code may be used by the garbage instructions for some extra mess—why not?
50.2.2 Replacing instructions with bloated equivalents
- MOV op1, op2can be replaced by thePUSH op2 / POP op1pair.
- JMP labelcan be replaced by thePUSH label / RETpair.IDAwill not show the references to the label.
- CALL labelcan be replaced by the following instructions triplet:PUSH label_after_CALL_instruction /
PUSH label / RET. - PUSH opcan also be replaced with the following instructions pair:SUB ESP, 4 (or 8) / MOV [ESP], op.
50.2.3 Always executed/never executed code
If the developer is sure that ESI at always 0 at that point:
mov esi, 1
... ; some code not touching ESI
dec esi
... ; some code not touching ESI
cmp esi, 0
jz real_code
; fake luggage
real_code:
The reverse engineer needs some time to get into it.
This is also called anopaque predicate.
Another example ( and again, the developer is sure that ESI is always zero):
add eax, ebx ; real code
mul ecx ; real code
add eax, esi ; opaque predicate. XOR, AND or SHL, etc, can be here instead of ADD.
50.2.4 Making a lot of mess
instruction 1
instruction 2
instruction 3