Skip to content

Obfuscation & Packing

Detecting packed binaries and obfuscated code is a critical step in reverse engineering malware. Packers compress or encrypt executable code to evade detection, while obfuscation techniques obscure logic and data to hinder analysis. Ghidra provides tools to identify these patterns, but requires a combination of static analysis, dynamic observation, and manual inspection. This section covers methods to detect packing and obfuscation, along with Ghidra-specific workflows for analysis.


Detecting Packed Binaries

Packed binaries often exhibit the following characteristics: - Unusual entropy: Packed code has high entropy (e.g., >7 bits), unlike clean binaries. - Missing imports: Packers often relocate imports into a separate section, leaving the main code with no direct references to system APIs. - Signature patterns: Some packers leave identifiable signatures (e.g., UPX's "UPX!" header). - Unusual section names: Packed binaries may have sections like .text with unexpected sizes or contents.

Using Ghidra to Identify Packing

  1. Load the binary into Ghidra and use the "Analyze All" feature to build a preliminary symbol table.
  2. Check entropy: Use Ghidra's "Entropy" tool (under Tools > Entropy) to visualize entropy distribution. Packed sections will show high entropy spikes.
  3. Inspect imports: Navigate to the "Imports" section in the Symbol Table. Packed binaries often have minimal or no imports.
  4. Search for packer signatures: Use the "Search" feature to look for known packer strings (e.g., "UPX!", "PECompact").

Example command to calculate entropy via Ghidra's scripting API:

import ghidra.app.script.GhidraScript;
import ghidra.program.model.address.Address;
import ghidra.program.model.data.DataType;
import ghidra.util.data.DataTypeUtils;

public class EntropyAnalysis extends GhidraScript {
    @Override
    protected void run() {
        // Calculate entropy for the entire binary
        Address start = getProgram().getAddressFactory().getDefaultAddressSpace().getAddress(0);
        Address end = getProgram().getMaxAddress();
        // Implementation omitted for brevity; use Ghidra's built-in entropy tool instead.
    }
}


Identifying Obfuscation Techniques

Obfuscation masks code logic, often through: - Control flow obfuscation: Unrolled loops, junk code insertion, or indirect jumps. - Name mangling: Renamed functions or variables to obscure intent. - Data encryption: Encrypted strings or payloads that require decryption at runtime.

Ghidra Analysis for Obfuscated Code

  1. Decompile functions: Use Ghidra's decompiler to view pseudocode. Obfuscated code may show:
  2. Unreadable variable names (e.g., var_12 instead of username).
  3. Complex control flow graphs with redundant branches.
  4. Search for patterns: Use the "Search" tool to find obfuscation markers like xor operations on strings or repeated jmp sequences.
  5. Dynamic analysis: If static analysis is insufficient, use Ghidra's "Run" feature to execute the binary in a sandboxed environment and monitor runtime behavior.

Example of decompiled obfuscated code:

int obfuscated_func() {
    int var_12 = 0;
    var_12 = var_12 ^ 0x42;
    if (var_12 == 0x42) {
        return 1;
    }
    return 0;
}
This snippet may represent a simple XOR-based obfuscation of a constant.


Analyzing Obfuscated Code with Ghidra

When dealing with heavily obfuscated code: 1. Isolate components: Use Ghidra's "Decompile" view to break down functions into smaller, manageable parts. 2. Look for anti-analysis: Check for int 0x80 or ud2 instructions, which may indicate anti-debugging checks. 3. Cross-reference symbols: If the binary has a symbol table, use it to map obfuscated functions to their intended purposes.

For example, if a function is named sub_401000, rename it to decrypt_payload if context suggests its purpose. This improves readability during analysis.


Key takeaways

  • Packed binaries often show high entropy, missing imports, or packer signatures, detectable via Ghidra's entropy analysis and symbol table inspection.
  • Obfuscation techniques like control flow alteration or data encryption require manual decompiler review and dynamic analysis.
  • Ghidra's "Analyze All" and "Decompile" features are essential for uncovering obfuscated logic, but manual intervention is often necessary for complex cases.