12.16. Countering Disassembly
Problem
An object file disassembler can produce an assembly language version of a binary, which can then be used to understand and possibly modify the binary.
Solution
Anti-disassembly tricks are useful in frustrating automatic analysis, but they generally will not hold up to a human review of the disassembly. Make sure to combine the methods presented in the discussion with data or code obfuscation techniques.
Discussion
Many disassemblers assume that long runs of
NULL
bytes are data, although some will
continue to disassemble regardless. In the Intel instruction set,
0x00 is the opcode for add al,
[eax]—a valid instruction. The following macros use
NULL bytes to increment the eax
register by pushing eax, loading the address of
the pushed value into eax, and executing
add al, [eax] instructions as many times as the
user specifies.
#define NULLPAD_START asm volatile ( \
"pushl %eax \n" \
"movl %esp, %eax\n")
#define NULLPAD asm volatile ("addb %al, (%eax)\n")
#define NULLPAD_END asm volatile ("popl %eax\n")
#define NULLPAD_10 NULLPAD_START; \
NULLPAD; NULLPAD; NULLPAD; NULLPAD; NULLPAD; \
NULLPAD_ENDThis is particularly effective if the value referenced by
eax—that is, the value at the top of the
stack—is used later in the program. Note that many
disassemblers that ignore runs of NULL bytes allow
the user to override this behavior.
To demonstrate the effect this macro has on disassemblers, the following source code was compiled and disassembled:
void my_func(void) ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access