reverse-skills-max: initial public release (restored, redacted, hardened)

This commit is contained in:
baradok609hecl1pq6qi
2026-10-20 02:17:15 +03:00
commit da24c2bd20
2227 changed files with 443931 additions and 0 deletions

View File

@@ -0,0 +1,9 @@
Apache License 2.0 — see the repository root LICENSE file for the full text.
Copyright the AnalystAIPack contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0

View File

@@ -0,0 +1,106 @@
---
name: reverse-engineering-binaries-with-ghidra
description: 'Uses Ghidra to disassemble and decompile a binary, navigate to key routines via
imports and strings, annotate decompiled code, and run headless scripts to automate
extraction of C2, crypto, and config. Activates for requests to reverse engineer with
Ghidra, decompile a binary, or script Ghidra headless analysis.'
domain: cybersecurity
subdomain: reverse-engineering
tags:
- reverse-engineering
- ghidra
- decompilation
- disassembly
- headless
- static-analysis
version: 1.0.0
author: analyst-ai-pack
license: Apache-2.0
mitre_attack:
- T1027
- T1140
- T1480
d3fend:
- D3-FA
- D3-FCR
references:
- 'Ghidra documentation — https://ghidra-sre.org/'
- 'Ghidra API (FlatProgramAPI / headless) — https://ghidra.re/ghidra_docs/api/'
---
# Reverse Engineering Binaries with Ghidra
## When to Use
- Static/dynamic triage has identified functionality that needs code-level understanding.
- You need to reverse a C2 protocol, decryption routine, or custom obfuscation.
- You want to extract hardcoded config (C2, keys, campaign IDs) from compiled code, or
automate extraction across many samples via headless scripts.
**Do not use** Ghidra as a first step for unknown samples — triage statically and behaviorally
first, and unpack before decompiling a packed binary.
## Prerequisites
- Ghidra 11.x with JDK 17+.
- An isolated analysis host.
- Familiarity with x86/x64 (or the target arch) and OS API conventions.
- The sample unpacked (decompiling packed code wastes effort).
## Safety & Handling
- Ghidra performs static analysis and does not run the sample, but still work in the lab.
- Treat any dumped/derived payloads as live samples.
## Workflow
### Step 1: Import and auto-analyze
Create a project, import the binary (Ghidra detects PE/ELF/Mach-O and arch), and run
auto-analysis with default analyzers.
### Step 2: Navigate to interesting code
Start from imports (Symbol Tree) and strings (Defined Strings). Cross-reference (`X`) from a
suspicious API or string to its callers to reach the relevant function quickly.
```text
VirtualAlloc/WriteProcessMemory -> injection logic
InternetOpen/WinHttp* -> C2
CryptEncrypt / custom XOR loops -> crypto/config decode
```
### Step 3: Annotate the decompiler output
Retype variables, rename functions, and add comments as you understand the code. Good naming
turns the decompiler into readable pseudo-C and compounds across a session.
### Step 4: Automate with headless scripts
For repeatable extraction, run Ghidra headless with a post-script. The bundled Python uses
`analyzeHeadless` to export functions/strings to JSON:
```bash
python scripts/analyst.py headless --ghidra /opt/ghidra --bin sample.bin --out out.json
```
### Step 5: Extract the target artifact
Recover the C2 string, key, or config and validate it against dynamic observations.
## Validation
- Renamed/retyped routines produce coherent pseudo-C consistent with observed behavior.
- Extracted config (C2/keys) matches what the sample uses at runtime.
- Headless export reproduces the interactive findings.
## Pitfalls
- Decompiling packed/obfuscated code — unpack first or the output is meaningless.
- Trusting decompiler types blindly; verify against the disassembly for crypto/pointer logic.
- Ignoring TLS callbacks/constructors that run before the entry point.
## References
- See [`references/api-reference.md`](references/api-reference.md) for the headless wrapper.
- Ghidra documentation and API (linked in frontmatter).

View File

@@ -0,0 +1,39 @@
# API Reference: Reverse Engineering Binaries with Ghidra
## Overview
`scripts/analyst.py` wraps Ghidra's `analyzeHeadless` to import a binary, run auto-analysis, and
optionally execute a post-script (such as a function/string exporter). It orchestrates Ghidra
and does not run the sample.
## Dependencies
| Package | Version | Purpose |
|---------|---------|---------|
| (stdlib) | — | subprocess, JSON, tempfile |
## External tools
| Tool | Version | Purpose |
|------|---------|---------|
| Ghidra | 11.x | Disassembly, decompilation, headless scripting |
| JDK | 17+ | Required by Ghidra |
## Core functions
### `run_headless(ghidra_path, binary, post_script, script_path, project_dir, timeout)`
Builds and runs the `analyzeHeadless` command (import, overwrite, delete temp project) and
returns the command, return code, and trimmed stdout/stderr.
## Usage
```bash
python scripts/analyst.py headless --ghidra /opt/ghidra --bin sample.bin \
--post-script ExportFunctions.py --script-path ./ghidra_scripts --out out.json
```
## Sources
- Ghidra documentation — https://ghidra-sre.org/
- Ghidra API / headless analyzer — https://ghidra.re/ghidra_docs/api/
- analyzeHeadless usage (Ghidra `support/analyzeHeadlessREADME.html`)

View File

@@ -0,0 +1,63 @@
#!/usr/bin/env python3
"""Wrapper for Ghidra headless analysis.
Drives ``support/analyzeHeadless`` to import a binary, run auto-analysis, and execute an
optional post-script (e.g. one that exports functions/strings to JSON). This orchestrates
Ghidra; it does not execute the sample. Ghidra performs static analysis only.
"""
from __future__ import annotations
import argparse
import json
import os
import subprocess # noqa: S404 - invoking the local Ghidra installation
import sys
import tempfile
def run_headless(ghidra_path: str, binary: str, post_script: str | None = None,
script_path: str | None = None, project_dir: str | None = None,
timeout: int = 1200) -> dict:
analyze = os.path.join(ghidra_path, "support",
"analyzeHeadless.bat" if os.name == "nt" else "analyzeHeadless")
if not os.path.isfile(analyze):
raise FileNotFoundError(f"analyzeHeadless not found at {analyze}")
project_dir = project_dir or tempfile.mkdtemp(prefix="ghidra_proj_")
cmd = [analyze, project_dir, "analyst-ai-pack",
"-import", binary, "-overwrite", "-deleteProject"]
if post_script:
cmd += ["-postScript", post_script]
if script_path:
cmd += ["-scriptPath", script_path]
proc = subprocess.run(cmd, capture_output=True, text=True, # noqa: S603
timeout=timeout, check=False)
return {
"command": " ".join(cmd),
"returncode": proc.returncode,
"stdout_tail": proc.stdout[-4000:],
"stderr_tail": proc.stderr[-2000:],
}
def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(description="Ghidra headless wrapper")
sub = parser.add_subparsers(dest="cmd", required=True)
p = sub.add_parser("headless")
p.add_argument("--ghidra", required=True, help="Ghidra install dir")
p.add_argument("--bin", required=True, dest="binary")
p.add_argument("--post-script")
p.add_argument("--script-path")
p.add_argument("--out")
args = parser.parse_args(argv)
result = run_headless(args.ghidra, args.binary, args.post_script, args.script_path)
text = json.dumps(result, indent=2)
if args.out:
with open(args.out, "w", encoding="utf-8") as fh:
fh.write(text)
print(text)
return 0 if result["returncode"] == 0 else 1
if __name__ == "__main__":
sys.exit(main())