  The strength of obfuscated software has increased over the recent years.
Compiler based obfuscation has become the de facto standard in the industry and
recent papers also show that injection of obfuscation techniques is done at the
compiler level. In this paper we discuss a generic approach for deobfuscation
and recompilation of obfuscated code based on the compiler framework LLVM. We
show how binary code can be lifted back into the compiler intermediate language
LLVM-IR and explain how we recover the control flow graph of an obfuscated
binary function with an iterative control flow graph construction algorithm
based on compiler optimizations and SMT solving. Our approach does not make any
assumptions about the obfuscated code, but instead uses strong compiler
optimizations available in LLVM and Souper Optimizer to simplify away the
obfuscation. Our experimental results show that this approach can be effective
to weaken or even remove the applied obfuscation techniques like constant
unfolding, certain arithmetic-based opaque expressions, dead code insertions,
bogus control flow or integer encoding found in public and commercial
obfuscators. The recovered LLVM-IR can be further processed by custom
deobfuscation passes that are now applied at the same level as the injected
obfuscation techniques or recompiled with one of the available LLVM backends.
The presented work is implemented in a deobfuscation tool called SATURN.
