There are three fundamental components in Control-Flow Integrity (CFI) enforcement. The first component is accurately recovering the policy (CFG). Usually, the more precise the policy is, the more security CFI improves, but precise CFG generation was considered hard without the support of source code. The second component is embedding the CFI policy securely. Current CFI enforcement usually inserts checks before indirect branches to consult a read-only table which stores the valid CFG information. However, this kind of read-only table can be overwritten by some kinds of attacks (e.g., the Rowhammer attack and data-oriented programming). The third component is to efficiently enforce the CFI policy. In current approaches CFI checks are always executed whenever there is an indirect control flow transfer. Therefore, it is critical to minimize the performance impact of CFI checks.
In this book, we propose novel solutions to handle these three fundamental components.To generate a precise CFI policy without the support of the source code, we systematically study two methods which recover CFI policy based on function signature matching at the binary level and propose our novel rule- and heuristic-based mechanism to more accurately recover function signature. To embed CFI policy securely, we design a novel platform which encodes the policy into the machine instructions directly without relying on consulting any read-only data structure, by making use of the idea of instruction-set randomization. Each basic block is encrypted with a key derived from the CFG. To efficiently enforce CFI policy, we make use of a mature dynamic code optimization platform called DynamoRIO to enforce the policy so that we are only required to do the CFI check when needed.