Without additional protections, analyzing and understanding algorithms in binaries is often not very hard—especially with decompilers. To increase analysis effort, code obfuscation techniques rewrite the syntax of a program so it’s harder to follow, while preserving the same semantics. Common techniques include obscuring control flow, hiding computations behind algebraic identities, and adding extra analysis layers that must be peeled away step by step.
In this exercise you’ll see a clean Fibonacci implementation and several obfuscated variants. Your goal is to examine each style, understand its impact on analysis, and explain what’s really going on.
-
Open
fib_obfuscatedin Ghidra or Binary Ninja. Look atfib_ref. What does it do? Note: Use the*.armv7for Binary Ninja Free; the free version doesn’t support AArch64. -
Analyze
fib_flat_switch. How does it work, and what does it compute? How would you "bypass" the obfuscation (i.e., simplify the control flow back to a normal loop/pseudocode)? -
Analyze
fib_flat_goto. How does the computed-goto dispatcher work, and what does it compute? How would you de-flatten or otherwise normalize the control flow? -
Analyze
fib_opaque(the opaque-predicate variant). What makes certain branches always true/false, and how can you simplify them away? -
Analyze the arithmetic/bitwise obfuscation in
fib_arithmetic(e.g., usings = (a ^ b) + ((a & b) << 1)instead ofs = a + b). Where is this used, and how would you normalize it back to standard arithmetic? -
Analyze
fib_vm. How does it work, and what does it compute? How would you "bypass" the obfuscation?