Reverse engineers Rust-compiled malware using IDA Pro and Ghidra, covering techniques for non-null-terminated fat-pointer strings, monomorphized/duplicated gene
复制下面这句话,粘贴给 Claude Code、Codex、Cursor 等 AI 编程工具,它会读取安装说明并在你确认后完成安装。
请阅读 https://ai.atlankj.com/install/asset/gh-reverse-engineering-rust-malware-ce286b6834c0 ,按照其中的说明把「reverse-engineering-rust-malware」安装到你(当前 AI 工具)中。执行前先告诉我将运行的命令和写入的位置,等我确认。
查看 AI 将读取的安装说明正在读取 GitHub 原文…
内容来自 GitHub 原始文件,由原作者维护。在 GitHub 查看
Rust has become increasingly popular for malware development due to its cross-compilation, memory safety guarantees, and the complexity it introduces for reverse engineers. Rust binaries contain the entire standard library statically linked, producing large binaries with extensive boilerplate code. Key challenges include non-null-terminated strings (Rust uses fat pointers with pointer+length), monomorphization generating duplicated generic code, complex error handling (Result/Option unwrap chains), and unfamiliar calling conventions. Decompiling Rust to C produces unhelpful output compared to C/C++ binaries. Tools like Ghidra scripts for crate extraction, and training focused on Rust-specific patterns (2024-2025) help address these challenges. Notable Rust malware includes BlackCat/ALPHV ransomware, Hive ransomware variants, and Buer Loader.
#!/usr/bin/env python3
"""Analyze Rust malware binary metadata and extract crate dependencies."""
import re
import sys
import json
def identify_rust_binary(data):
"""Check if binary is Rust-compiled and extract version info."""
indicators = {
"rust_panic_strings": bool(re.search(rb'panicked at', data)),
"rust_unwrap": bool(re.search(rb'called.*unwrap.*on.*None', data)),
"core_panic": bool(re.search(rb'core::panicking', data)),
"std_rt": bool(re.search(rb'std::rt::lang_start', data)),
"cargo_path": bool(re.search(rb'\.cargo[/\\]registry', data)),
"rustc_version": None,
}
version = re.search(rb'rustc\s+(\d+\.\d+\.\d+)', data)
if version:
indicators["rustc_version"] = version.group(1).decode()
is_rust = sum(1 for v in indicators.values() if v) >= 2
return is_rust, indicators
def extract_crates(data):
"""Extract Rust crate (dependency) names from binary strings."""
crate_pattern = re.compile(
rb'(?:crates\.io-[a-f0-9]+/|\.cargo/registry/src/[^/]+/)'
rb'([\w-]+)-(\d+\.\d+\.\d+)'
)
crates = {}
for match in crate_pattern.finditer(data):
name = match.group(1).decode()
version = match.group(2).decode()
crates[name] = version
# Also check for common malware-relevant crates
suspicious_crates = {
"reqwest": "HTTP client",
"hyper": "HTTP library",
"tokio": "Async runtime",
"aes": "AES encryption",
"chacha20": "ChaCha20 encryption",
"rsa": "RSA encryption",
"ring": "Crypto library",
"base64": "Base64 encoding",
"winapi": "Windows API bindings",
"winreg": "Registry access",
"sysinfo": "System information",
"screenshots": "Screen capture",
"clipboard": "Clipboard access",
"keylogger": "Key logging",
}
capabilities = []
for crate_name, description in suspicious_crates.items():
if crate_name in crates:
capabilities.append({
"crate": crate_name,
"version": crates[crate_name],
"capability": description,
})
return crates, capabilities
def extract_rust_strings(data):
"""Extract strings handling Rust's non-null-terminated format."""
# Rust strings are stored as pointer+length, but string literals
# are often in .rodata as contiguous sequences
strings = []
ascii_pattern = re.compile(rb'[\x20-\x7e]{8,500}')
for match in ascii_pattern.finditer(data):
s = match.group().decode('ascii')
# Filter for malware-relevant strings
keywords = ['http', 'socket', 'encrypt', 'decrypt', 'shell',
'exec', 'cmd', 'upload', 'download', 'persist',
'registry', 'mutex', 'pipe', 'inject']
if any(kw in s.lower() for kw in keywords):
strings.append(s)
return strings
if __name__ == "__main__":
if len(sys.argv) < 2:
print(f"Usage: {sys.argv[0]} <rust_binary>")
sys.exit(1)
with open(sys.argv[1], 'rb') as f:
data = f.read()
is_rust, indicators = identify_rust_binary(data)
print(f"[{'+'if is_rust else '-'}] Rust binary: {is_rust}")
print(json.dumps(indicators, indent=2, default=str))
crates, capabilities = extract_crates(data)
print(f"\n[+] Crates ({len(crates)}):")
for name, ver in sorted(crates.items()):
print(f" {name} v{ver}")
if capabilities:
print(f"\n[!] Suspicious capabilities:")
for cap in capabilities:
print(f" {cap['crate']} -> {cap['capability']}")
strings = extract_rust_strings(data)
if strings:
print(f"\n[+] Suspicious strings ({len(strings)}):")
for s in strings[:20]:
print(f" {s}")