---
name: rt-binary-reverse-engineering
description: "Binary reverse engineering skill for authorized red team engagements. Ghidra and IDA Pro workflow for decompilation, x64dbg dynamic analysis, .NET assembly decompilation with dnSpy/ILSpy, Java JAR analysis, ELF binary analysis, finding hardcoded credentials and API keys in binaries, license check bypassing, and understanding proprietary protocol implementations. Use when analyzing compiled applications, firmware, or custom protocols."
---

# rt-binary-reverse-engineering — Binary Analysis & Reverse Engineering

## Overview

Binary reverse engineering analyzes compiled executables to understand their behavior without source code. In red team engagements, this discovers hardcoded credentials, hidden functionality, bypassable authentication, and proprietary protocol weaknesses.

---

## Phase 1 — Initial Triage (Before Disassembly)

```bash
# File type identification
file target_binary
# ELF 64-bit LSB executable → Linux binary
# PE32+ executable → Windows binary
# Mach-O → macOS binary

# Basic string extraction (fastest wins)
strings target_binary | grep -iE "password|secret|key|token|admin|api|url|http"
strings -n 8 target_binary | grep -iE "BEGIN.*KEY|PRIVATE|jwt"

# Detect packing/obfuscation
die target_binary        # Detect-It-Easy
upx -t target_binary     # Check if UPX packed
entropy target_binary    # High entropy (>7.5) = encrypted/packed sections

# Symbols and imports
nm target_binary         # Symbol table (if not stripped)
objdump -d target_binary # Disassembly
ldd target_binary        # Dynamic library dependencies
readelf -a target_binary # Full ELF headers

# PE analysis (Windows)
pecheck target.exe
dumpbin /imports target.exe  # Imported functions
dumpbin /exports target.exe  # Exported functions

# Quick wins: look for these imports
# CreateProcess, WinExec, ShellExecute = code execution
# CryptDecrypt, CryptImportKey = crypto operations
# InternetOpenUrl, HttpSendRequest = network communication
# RegOpenKey, RegSetValue = registry operations
```

---

## Phase 2 — Static Analysis with Ghidra

```bash
# Install Ghidra
# https://ghidra-sre.org → download → ./ghidraRun

# Headless analysis (scriptable)
./analyzeHeadless /tmp/ghidra_project MyProject \
  -import target_binary \
  -postScript PrintStrings.py \
  -deleteProject

# Key Ghidra workflow:
# 1. Import binary → Auto-analyze
# 2. Symbol Tree → Functions → main()
# 3. Decompiler window → clean C-like pseudocode
# 4. Search → Memory → search for strings (hardcoded strings)
# 5. References → find all callers of crypto/auth functions
```

```python
# Ghidra script: find hardcoded strings (run in Script Manager)
from ghidra.app.script import GhidraScript
from ghidra.program.model.data import StringDataType

class FindSecrets(GhidraScript):
    def run(self):
        keywords = ["password", "secret", "api_key", "token", "admin"]
        for ref in currentProgram.getReferenceManager().getReferenceIterator(None):
            addr = ref.getToAddress()
            data = getDataAt(addr)
            if data and isinstance(data.getDataType(), StringDataType):
                val = str(data.getValue()).lower()
                for kw in keywords:
                    if kw in val:
                        print(f"[SECRET] {addr}: {data.getValue()}")
```

---

## Phase 3 — .NET Binary Analysis (dnSpy / ILSpy)

```bash
# .NET binaries contain IL bytecode → decompile to near-original C#

# dnSpy (best for .NET — also debugger)
# https://github.com/dnSpy/dnSpy
# Open .exe/.dll → full source code decompilation

# ILSpy (CLI)
ilspycmd target.exe -o ./decompiled/

# dotPeek (JetBrains — free)
# Open → decompile → navigate class hierarchy

# What to look for in decompiled .NET:
grep -r "password\|connectionString\|ApiKey\|secret" ./decompiled/ --include="*.cs"
grep -r "hardcoded\|TODO.*password\|admin123" ./decompiled/

# .NET config files (often not encrypted)
cat ./decompiled/App.config
cat web.config | grep -i "password\|connectionString"

# Assembly manipulation: patch license check
# 1. Open in dnSpy
# 2. Find: IsLicensed() or CheckLicense()
# 3. Right-click method → Edit Method
# 4. Change return false → return true
# 5. File → Save Module
```

---

## Phase 4 — Java JAR Analysis

```bash
# Decompile JAR
# jadx — best Java decompiler
jadx -d ./decompiled_java/ target.jar
# Browse ./decompiled_java/ as Java source

# procyon (alternative)
java -jar procyon-decompiler.jar target.jar -o ./decompiled/

# Look for hardcoded secrets
grep -r "password\|apiKey\|secret\|jdbc:" ./decompiled_java/ --include="*.java"

# Extract embedded resources
jar xf target.jar
# Inspect: META-INF/, resources/, application.properties

cat application.properties | grep -i "password\|secret\|datasource"
cat META-INF/MANIFEST.MF  # Entry point class

# Decompile Android APK (Dalvik bytecode)
jadx -d ./apk_decompiled/ app.apk
grep -r "apiKey\|password\|secret\|BuildConfig" ./apk_decompiled/
cat ./apk_decompiled/resources/res/values/strings.xml | grep -i "key\|token\|password"
```

---

## Phase 5 — Dynamic Analysis with x64dbg

```bash
# x64dbg: Windows debugger for 32/64-bit binaries
# https://x64dbg.com

# Workflow:
# 1. Open target in x64dbg
# 2. Run → break at entry point
# 3. Search → All User Modules → String References → search "password"
# 4. Set breakpoint at identified function → Run → inspect values

# Key techniques:
# Patch jump: change JE (74) to JMP (EB) to bypass license check
# Patch comparison: change CMP result to always succeed
# Memory view: inspect decrypted strings at runtime
# API logger: log all WinAPI calls → find authentication logic
```

```python
# Automated dynamic analysis with frida (no source needed)
# Hook any function by address or name

import frida, sys

script_code = """
// Hook license check function at address 0x401234
Interceptor.attach(ptr("0x401234"), {
    onEnter: function(args) {
        console.log("[*] License check called");
        console.log("    Arg 0:", args[0].readUtf8String());
    },
    onLeave: function(retval) {
        console.log("[*] License check returned:", retval);
        retval.replace(1);  // Force return true (bypass)
    }
});

// Hook all calls to strcmp (find credential comparisons)
Interceptor.attach(Module.findExportByName(null, "strcmp"), {
    onEnter: function(args) {
        var s1 = args[0].readUtf8String();
        var s2 = args[1].readUtf8String();
        if (s1 && s2 && (s1.length > 3 || s2.length > 3)) {
            console.log("[strcmp]", s1, "vs", s2);
        }
    }
});
"""

process = frida.spawn(["./target_binary"])
session = frida.attach(process)
script = session.create_script(script_code)
script.load()
frida.resume(process)
sys.stdin.read()
```

---

## Phase 6 — Finding Hardcoded Credentials

```bash
# Automated binary secret scanning
# trufflehog (supports binaries)
trufflehog filesystem ./target_directory/ --json | jq '.SourceMetadata.Data.Filesystem.file + ": " + .Raw'

# YARA rules for credential patterns in binaries
cat > secrets.yar << 'EOF'
rule HardcodedPassword {
    strings:
        $pass1 = "password" nocase
        $pass2 = "passwd" nocase
        $key1 = "api_key" nocase
        $key2 = "apikey" nocase
        $aws = /AKIA[0-9A-Z]{16}/
        $jwt = /eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/
    condition:
        any of them
}
EOF
yara -r secrets.yar ./target_binary

# binwalk — extract embedded content from binaries
binwalk -e target_firmware.bin
# Extracts: filesystems, compressed data, certificates, private keys
ls _target_firmware.bin.extracted/

# floss — deobfuscate strings in malware/obfuscated binaries
floss target.exe | grep -iE "http|password|key|token"
```

---

## Phase 7 — Protocol Reverse Engineering

```bash
# Capture traffic from binary + analyze
# 1. Run binary under strace (Linux)
strace -e trace=network,read,write -xx ./target_binary 2>&1 | grep -A2 "sendto\|write"

# 2. Capture with Wireshark/tcpdump
tcpdump -i lo -w capture.pcap &
./target_binary
# Analyze capture.pcap in Wireshark

# 3. Hook socket calls with frida
cat > proto_hook.js << 'EOF'
var send = Module.findExportByName("libc.so.6", "send");
Interceptor.attach(send, {
    onEnter: function(args) {
        var len = args[2].toInt32();
        if (len > 0) {
            console.log("[send] " + len + " bytes:");
            console.log(hexdump(args[1], {length: Math.min(len, 256)}));
        }
    }
});
EOF
frida -l proto_hook.js ./target_binary

# 4. Identify protocol fields
# - Fixed headers (magic bytes)
# - Length fields
# - Checksum/CRC fields
# - Encrypted vs cleartext regions
```

---

## Skill Levels

**BEGINNER:** strings + grep for credentials · jadx for .NET/Java · floss for obfuscated strings

**INTERMEDIATE:** Ghidra decompilation · x64dbg breakpoints · Frida for dynamic hooking · .NET patching with dnSpy

**ADVANCED:** Custom Ghidra scripts · Protocol reverse engineering · Anti-debug bypass · Binary patching

**EXPERT:** Firmware analysis with binwalk · Custom deobfuscation · Vulnerability research from decompiled code · 0-day discovery

---

## References

- Ghidra: https://ghidra-sre.org
- x64dbg: https://x64dbg.com
- jadx: https://github.com/skylot/jadx
- dnSpy: https://github.com/dnSpy/dnSpy
- Frida: https://frida.re
- Practical Binary Analysis (book): https://nostarch.com/binaryanalysis
- MITRE T1027: https://attack.mitre.org/techniques/T1027/
