Reverse Engineering with Ghidra: From Zero to Hero

Blacksec

Administrator
Staff member
πŸ”§ Reverse Engineering with Ghidra: From Zero to Hero πŸ”§


> Posted by: binary_wizard | Rank: Legend | Joined: 2021 [/I]



β€’ Ghidra setup & navigation
β€’ Static analysis techniques
β€’ Dynamic analysis with debugger
β€’ Deobfuscation strategies
β€’ Real-world reverse engineering case studies

Reverse engineering is the superpower every security professional needs.

I've been reverse engineering binaries for 6+ years. Today I'm sharing my complete workflow with Ghidra - the open-source RE tool from the NSA.

---

━━━ GHIDRA SETUP ━━━[/B]

Code:
# === Installation ===
# Download from: https://ghidra.re/
# Extract and run:
cd ghidra_10.3_PUBLIC
./ghidraRun.sh

# === First-time Setup ===
1. Create new project (File β†’ New Project)
2. Import binary (File β†’ Import File)
3. Select analyzer (Windows x86-64 / x86)
4. Let Ghidra analyze (takes 1-10 mins depending on size)

---

━━━ NAVIGATION QUICKSTART ━━━


Code:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    GHIDRA INTERFACE                         β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Project Browser β”‚  Code Browser                           β”‚
β”‚  β€’ Projects      β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β€’ Symbols       β”‚  β”‚Functions β”‚Data Typesβ”‚Comments     β”‚  β”‚
β”‚  β€’ Libraries     β”‚  β”‚          β”‚          β”‚             β”‚  β”‚
β”‚                  β”‚  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€  β”‚
β”‚                  β”‚  β”‚Disassemblyβ”‚Decompilerβ”‚Symbol Tree  β”‚  β”‚
β”‚                  β”‚  β”‚          β”‚          β”‚             β”‚  β”‚
β”‚                  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Console / Task Progress                                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

KEYBOARD SHORTCUTS:
β€’ N - Create new function
β€’ L - Rename variable
β€’ Y - Change variable type
β€’ Space - Toggle assembly/decompiler
β€’ Enter - Follow reference
β€’ Escape - Go back

---

━━━ ANALYSIS WORKFLOW ━━━


Code:
# === Step 1: Initial Recon ===
1. Check file type: file malware.exe
2. Check strings: strings malware.exe | head -50
3. Check imports: objdump -p malware.exe
4. Check sections: readelf -S malware.exe

# === Step 2: Ghidra Analysis ===
1. Import into Ghidra
2. Look at entry point (_main, WinMain, DllMain)
3. Find interesting functions (check imports)
4. Analyze string references
5. Look for encryption routines

# === Step 3: Function Analysis ===
1. Double-click function in Symbol Tree
2. Read decompiler output (right panel)
3. Cross-reference: right-click β†’ References to
4. Add comments: press C key
5. Rename variables: press L key

# === Step 4: Debugging ===
1. Attach debugger (Debug β†’ Attach to Process)
2. Set breakpoints (double-click in disassembly)
3. Step through (F8 = Step Over, F7 = Step Into)
4. Watch registers (Registers window)
5. Memory view (Memory map window)

---

━━━ DECOMPILER TIPS ━━━


Code:
# Ghidra decompiler output looks like C code
# Here's how to read it:

// Original decompiled code:
void __thiscall sub_401000(int this)
{
  int v1; // eax
  int v2; // edx
  char *v3; // esi
  char *v4; // edi
  
  v1 = *(_DWORD *)(this + 8);
  v2 = v1;
  v3 = (char *)(v1 + 16);
  v4 = (char *)sub_401200(v3);
  // ...
}

// What this actually does:
// - 'this' is the object pointer
// - *(_DWORD *)(this + 8) gets a member variable
// - sub_401200 is a function call
// - v3 and v4 are pointers being manipulated

// TIP: Rename variables to meaningful names!
// Click variable β†’ press L β†’ type new name

---

━━━ COMMON PATTERNS ━━━


String Decryption:
Code:
// Many malware use string encryption
// Look for this pattern:
void decrypt_strings(char *encrypted, char *decrypted, int length)
{
  for (int i = 0; i < length; i++)
  {
    decrypted[i] = encrypted[i] ^ 0x41;  // XOR key
  }
}

// Ghidra tip: Find all XOR operations
// Search β†’ Hex Search β†’ 41 00 00 00

Anti-Debugging:
Code:
// Common anti-debug techniques:
IsDebuggerPresent()     // Windows API
NtQueryInformationProcess()  // Check debugger flag
CheckRemoteDebuggerPresent()
Time-based checks:
  GetTickCount() - start_time > threshold
  RDTSC instruction (CPU timestamp)

// In Ghidra: Search for these function names

Network Communication:
Code:
// Look for socket API calls:
WSAStartup()     // Initialize Winsock
socket()         // Create socket
connect()        // Connect to C2
send() / recv()  // Send/receive data
ioctlsocket()    // Set socket options (non-blocking)

// Ghidra: Search for IP addresses in strings
// Search β†’ String β†’ Look for 127.0.0.1 or external IPs

---

━━━ GHIDRA SCRIPTING ━━━


Code:
#!/usr/bin/env python3
"""
Ghidra Script for Automated Analysis
Run this in Ghidra's Script Manager
"""
# Ghidra Python API basics:
from ghidra.program.model.listing import *
from ghidra.program.model.symbol import *
from ghidra.util.task import *

# Get current program
program = currentProgram
listing = program.getListing()

# Get all functions
functions = program.getFunctionManager().getFunctions(True)

print(f"[*] Found {functions.__len__()} functions")

# Analyze each function
for func in functions:
    name = func.getName()
    if "encrypt" in name.lower() or "decrypt" in name.lower():
        print(f"[+] Found crypto function: {name}")
        print(f"    Address: {hex(func.getEntryPoint().getOffset())}")
        
    # Check for suspicious API calls
    references = func.getReferences()
    for ref in references:
        ref_target = ref.getToAddress()
        ref_name = ref_target.getSymbolTable().getPrimarySymbol(ref_target).getName()
        if any(s in ref_name.lower() for s in ['exec', 'system', 'shell', 'socket', 'connect']):
            print(f"    [!] Calls: {ref_name}")

print("[*] Analysis complete")

---

━━━ REAL-WORLD EXAMPLE ━━━


Reversing a Simple Ransomware:
Code:
Step 1: String Analysis
- Found: ".cry", "ransom.txt", "bitcoin"
- Conclusion: Cry ransomware variant

Step 2: Entry Point Analysis
- Entry: 0x401000 (WinMain)
- Calls: CreateFile, WriteFile, CryptEncrypt
- Conclusion: File encryption with hardcoded key

Step 3: Crypto Analysis
- Algorithm: AES-256-CBC
- Key derivation: PBKDF2 with salt
- Key storage: Embedded in binary (decrypted at runtime)

Step 4: Network Analysis
- C2 domain: cmd.evil.com (hardcoded)
- Protocol: Custom binary protocol
- Exfiltration: Encrypted with RSA-2048

Step 5: Persistence
- Registry: HKLM\\Run\\SystemUpdate
- Scheduled task: Daily encryption run

---

━━� GHIDRA VS IDA PRO ━━━


Code:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚    Feature  β”‚    Ghidra      β”‚    IDA Pro     β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚    Cost     β”‚    FREE        β”‚    $3000+/yr   β”‚
β”‚    Platform β”‚    Cross-plat  β”‚    Win/Linux   β”‚
β”‚    Decompilerβ”‚   Good         β”‚   Excellent    β”‚
β”‚    Plugins  β”‚   Lots (Java)  β”‚   Lots (C/Py)  β”‚
β”‚    Debuggingβ”‚   Basic        β”‚   Advanced     β”‚
β”‚    Learning β”‚   Easier       β”‚   Steeper      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

My recommendation: Start with Ghidra (free), upgrade to IDA Pro when you need advanced debugging.

---

━━━ TL;DR ━━━


Code:
βœ… Start with strings and imports
βœ… Analyze entry point first
βœ… Rename variables (press L)
βœ… Comment everything (press C)
βœ… Use cross-references heavily
βœ… Script repetitive tasks
βœ… Combine static + dynamic analysis

---

What's your RE workflow? Drop your Ghidra tips below.
Next: Advanced buffer overflow exploitation.

Last edited by binary_wizard; 20 minutes ago.



[SIG]━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
binary_wizard | Legend | Reverse Engineer
⚑ "Every binary has a story, I just read it backwards" ⚑
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[/SIG]
[/b][/b][/b][/b][/b][/b][/b][/b]
 
Top