3.17. OBFUSCATION
mov ebx, offset username
cmp byte ptr [ebx], 'j'
jnz fail
cmp byte ptr [ebx+1], 'o'
jnz fail
cmp byte ptr [ebx+2], 'h'
jnz fail
cmp byte ptr [ebx+3], 'n'
jnz fail
jz it_is_john
In both cases, it is impossible to find these strings straightforwardly in a hex editor.
By the way, this is a way to work with the strings when it is impossible to allocate space for them in the
data segment, for example in aPIC^21 or in shellcode.
Another method is to usesprintf()for the construction:
sprintf(buf, "%s%c%s%c%s", "hel",'l',"o w",'o',"rld");
The code looks weird, but as a simple anti-reversing measure, it may be helpful.
Text strings may also be present in encrypted form, then every string usage is to be preceded by a string
decrypting routine. For example:8.5.2 on page 822.
3.17.2 Executable code
Inserting garbage
Executable code obfuscation implies inserting random garbage code between real one, which executes
but does nothing useful.
A simple example:
Listing 3.79: original code
add eax, ebx
mul ecx
Listing 3.80: 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?
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.
(^21) Position Independent Code