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_END
This 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) ...
Get Secure Programming Cookbook for C and C++ now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.