Tools used to obfuscate compiled binary programs are generically referred to as packers.
This term stems from the fact that one technique for obfuscating a binary program is
simply to compress the program, as compressed data tends to look far more random,
and certainly does not resemble machine language. For the program to actually execute
on the target system, it must remain a valid executable for the target platform. The
standard approach taken by most packers is to embed an unpacking stub into the
packed software and to modify the program entry point to point to the unpacking stub.
When the packed software executes, the operating system reads the new entry point and
initiates execution of the packed program at the unpacking stub. The purpose of the
unpacking stub is to restore the packed program to its original state and then to transfer
control to the restored program.
Packers vary significantly in their degree of sophistication. The most basic packers
simply perform compression of a binary’s code and data sections. More sophisticated
packers not only compress but also perform some degree of encryption of the binary’s
sections. Finally, many packers will take steps to obfuscate a binary’s import table by
compressing or encrypting the list of functions and libraries that the binary depends
upon. In this last case, the unpacking stub must be sophisticated enough to perform
many of the functions of the dynamic loader, including loading any libraries that will
be required by the unpacked binary and obtaining the addresses of all required functions
within those libraries. The most obvious way to do this is to leverage available
systems API functions such as the Windows LoadLibrary() and GetProcAddress()
functions. Each of these functions requires ASCII input to specify the name of a
library or function, leaving the binary susceptible to strings analysis.