/pe-analysis
Activate this skill whenever the user mentions PE analysis, PE file, PE header, portable executable, Windows executable analysis, EXE analysis, DLL analysis, SYS driver analysis, OCX analysis, PE structure, PE format, PE parsing, PE triage, PE inspection, binary headers, file
Claude Code
$ npx -y skills add ogrodev/fsociety --skill pe-analysis --agent claude-code
Codex
$ npx skills add ogrodev/fsociety --skill pe-analysis -a codex -y
Cursor
$ npx skills add ogrodev/fsociety --skill pe-analysis -a cursor -y
Gemini CLI
$ npx skills add ogrodev/fsociety --skill pe-analysis -a gemini-cli -y
GitHub Copilot
$ npx skills add ogrodev/fsociety --skill pe-analysis -a github-copilot -y
OpenCode
$ npx skills add ogrodev/fsociety --skill pe-analysis -a opencode -y
Windsurf
$ npx skills add ogrodev/fsociety --skill pe-analysis -a windsurf -y
SKILL.md
pe-analysis.SKILL.mdname: pe-analysis
description: |
Activate this skill whenever the user mentions PE analysis, PE file, PE header, portable executable,
Windows executable analysis, EXE analysis, DLL analysis, SYS driver analysis, OCX analysis,
PE structure, PE format, PE parsing, PE triage, PE inspection, binary headers, file headers,
DOS header, MZ header, COFF header, optional header, PE signature, image base, entry point,
AddressOfEntryPoint, section table, section headers, section entropy, section permissions,
.text section, .rdata section, .rsrc section, .reloc section, .data section, UPX section,
import table, IAT, import address table, import directory, DLL imports, suspicious imports,
API hashing, GetProcAddress hashing, delayed imports, bound imports,
export table, EAT, export address table, DLL exports, forwarded exports, ordinal exports,
resource table, resource directory, embedded resources, PE resources, resource extraction,
version info, file version, manifest, embedded manifest, icon extraction,
overlay data, appended data, PE overlay, data after last section,
PE anomalies, header anomalies, suspicious PE, malformed PE, corrupted PE,
timestamp analysis, compile time, TimeDateStamp, checksum validation, PE checksum,
rich header, Rich signature, linker info, compiler detection,
debug directory, PDB path, debug info, CodeView,
authenticode, digital signature, signed binary, certificate validation,
TLS callbacks, TLS directory, thread local storage,
data directories, CLR header, .NET PE, COM descriptor,
pefile, pestudio, PE-bear, CFF Explorer, dumpbin, objdump, readpe,
packed binary detection, packer identification, UPX detection, section padding,
security features check, ASLR, DEP, NX, CFG, SafeSEH, guard flags,
PE file triage, unknown binary triage, suspicious binary, malware triage,
binary classification, executable classification, initial binary assessment.
version: 2.0.0
PE File Analysis
Portable Executable analysis is the foundation of Windows binary reverse engineering. Every .exe, .dll, .sys, .ocx, and .scr on Windows follows the PE format. Master PE structure and you can triage unknown binaries in minutes -- determine if they are packed, what they do, what anomalies they exhibit, and whether they warrant deeper analysis.
Triage Workflow
Follow this sequence when analyzing an unknown PE file. Each step builds on the previous one.
Step 1 — Compute Hashes and Basic Identification
Hash the binary first. Check hashes against known databases before spending time on manual analysis.
# SHA256 + MD5 + file type
node ${CLAUDE_PLUGIN_ROOT}/scripts/binary-hasher.js hash <binary>
file <binary>
# Check analysis database for prior work
node ${CLAUDE_PLUGIN_ROOT}/scripts/analysis-tracker.js check <sha256> pe-analysisRecord the hash immediately. Every subsequent finding references this hash.
Step 2 — Header Analysis
Extract PE headers to determine architecture, compile time, entry point, and security features.
# Full header dump with radare2
r2 -qc 'iH' <binary>
r2 -qc 'iI' <binary>
import pefile, time
pe = pefile.PE('<binary>')
# Compile timestamp
ts = pe.FILE_HEADER.TimeDateStamp
print(f"Compile time: {time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(ts))} UTC")
print(f"Machine: {hex(pe.FILE_HEADER.Machine)}")
print(f"Entry point: {hex(pe.OPTIONAL_HEADER.AddressOfEntryPoint)}")
print(f"Image base: {hex(pe.OPTIONAL_HEADER.ImageBase)}")
print(f"Subsystem: {pe.OPTIONAL_HEADER.Subsystem}")
# Security features
flags = pe.OPTIONAL_HEADER.DllCharacteristics
print(f"ASLR: {bool(flags & 0x40)}, DEP: {bool(flags & 0x100)}, CFG: {bool(flags & 0x4000)}")
print(f"No SEH: {bool(flags & 0x400)}, Force integrity: {bool(flags & 0x80)}")Check for anomalies: future timestamps, epoch zero, entry point outside `.text`, missing ASLR/DEP.
See `references/pe-headers.md` for complete field reference.
Step 3 — Section Analysis
Sections reveal packing, encryption, and structural manipulation.
r2 -qc 'iS' <binary> # Section table
r2 -qc 'iSS' <binary> # Sections with entropy
for s in pe.sections:
name = s.Name.decode().rstrip('\x00')
entropy = s.get_entropy()
raw = s.SizeOfRawData
virt = s.Misc_VirtualSize
ratio = virt / raw if raw > 0 else float('inf')
chars = s.Characteristics
rwx = f"{'R' if chars & 0x40000000 else '-'}{'W' if chars & 0x80000000 else '-'}{'X' if chars & 0x20000000 else '-'}"
packed = "PACKED" if entropy > 7.0 else "HIGH" if entropy > 6.5 else ""
inflated = "INFLATED" if ratio > 10 else ""
print(f"{name:8s} raw={raw:>8d} virt={virt:>8d} ratio={ratio:>6.1f} entropy={entropy:.2f} {rwx} {packed} {inflated}")Red flags: entropy > 7.0, VirtualSize >> RawSize, RWX permissions, packer section names (.UPX, .aspack, .themida, .vmp).
See `references/section-analysis.md` for section deep dive.
Step 4 — Import Analysis
Imports reveal the binary's capabilities. Missing or minimal imports suggest packing or dynamic resolution.
r2 -qc 'ii' <binary>
r2 -qc 'ii~CreateRemote' <binary> # Search for injection APIs
r2 -qc 'ii~Virtual' <binary> # Search for memory manipulation
if hasattr(pe, 'DIRECTORY_ENTRY_IMPORT'):
for entry in pe.DIRECTORY_ENTRY_IMPORT:
dll = entry.dll.decode()
funcs = [i.name.decode() if i.name else f"ord#{i.ordinal}" for i in entry.imports]
print(f"{dll} ({len(funcs)} imports): {', '.join(funcs[:5])}{'...' if len(funcs) > 5 else ''}")
else:
print("NO IMPORT TABLE — likely packed or manually resolved")Few imports (< 5 functions) from kernel32.dll only = strong packing indicator. Look for LoadLibrary + GetProcAddress as the only imports -- this means the binary resolves everything at runtime.
See `references/import-export-tables.md` for import/export deep dive.
Step 5 — Resource Analysis
Resources can contain embedded
Read more
name: pe-analysis description: | Activate this skill whenever the user mentions PE analysis, PE file, PE header, portable executable, Windows executable analysis, EXE analysis, DLL analysis, SYS driver analysis, OCX analysis, PE structure, PE format, PE parsing, PE triage, PE inspection, binary headers, file headers, DOS header, MZ header, COFF header, optional header, PE signature, image base, entry point, AddressOfEntryPoint, section table, section headers, section entropy, section permissions, .text section, .rdata section, .rsrc section, .reloc section, .data section, UPX section, import table, IAT, import address table, import directory, DLL imports, suspicious imports, API hashing, GetProcAddress hashing, delayed imports, bound imports, export table, EAT, export address table, DLL exports, forwarded exports, ordinal exports, resource table, resource directory, embedded resources, PE resources, resource extraction, version info, file version, manifest, embedded manifest, icon extraction, overlay data, appended data, PE overlay, data after last section, PE anomalies, header anomalies, suspicious PE, malformed PE, corrupted PE, timestamp analysis, compile time, TimeDateStamp, checksum validation, PE checksum, rich header, Rich signature, linker info, compiler detection, debug directory, PDB path, debug info, CodeView, authenticode, digital signature, signed binary, certificate validation, TLS callbacks, TLS directory, thread local storage, data directories, CLR header, .NET PE, COM descriptor, pefile, pestudio, PE-bear, CFF Explorer, dumpbin, objdump, readpe, packed binary detection, packer identification, UPX detection, section padding, security features check, ASLR, DEP, NX, CFG, SafeSEH, guard flags, PE file triage, unknown binary triage, suspicious binary, malware triage, binary classification, executable classification, initial binary assessment. version: 2.0.0
PE File Analysis
Portable Executable analysis is the foundation of Windows binary reverse engineering. Every .exe, .dll, .sys, .ocx, and .scr on Windows follows the PE format. Master PE structure and you can triage unknown binaries in minutes -- determine if they are packed, what they do, what anomalies they exhibit, and whether they warrant deeper analysis.
Triage Workflow
Follow this sequence when analyzing an unknown PE file. Each step builds on the previous one.
Step 1 — Compute Hashes and Basic Identification
Hash the binary first. Check hashes against known databases before spending time on manual analysis.
# SHA256 + MD5 + file type
node ${CLAUDE_PLUGIN_ROOT}/scripts/binary-hasher.js hash <binary>
file <binary>
# Check analysis database for prior work
node ${CLAUDE_PLUGIN_ROOT}/scripts/analysis-tracker.js check <sha256> pe-analysisRecord the hash immediately. Every subsequent finding references this hash.
Step 2 — Header Analysis
Extract PE headers to determine architecture, compile time, entry point, and security features.
# Full header dump with radare2 r2 -qc 'iH' <binary> r2 -qc 'iI' <binary>
import pefile, time
pe = pefile.PE('<binary>')
# Compile timestamp
ts = pe.FILE_HEADER.TimeDateStamp
print(f"Compile time: {time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(ts))} UTC")
print(f"Machine: {hex(pe.FILE_HEADER.Machine)}")
print(f"Entry point: {hex(pe.OPTIONAL_HEADER.AddressOfEntryPoint)}")
print(f"Image base: {hex(pe.OPTIONAL_HEADER.ImageBase)}")
print(f"Subsystem: {pe.OPTIONAL_HEADER.Subsystem}")
# Security features
flags = pe.OPTIONAL_HEADER.DllCharacteristics
print(f"ASLR: {bool(flags & 0x40)}, DEP: {bool(flags & 0x100)}, CFG: {bool(flags & 0x4000)}")
print(f"No SEH: {bool(flags & 0x400)}, Force integrity: {bool(flags & 0x80)}")Check for anomalies: future timestamps, epoch zero, entry point outside `.text`, missing ASLR/DEP.
See `references/pe-headers.md` for complete field reference.
Step 3 — Section Analysis
Sections reveal packing, encryption, and structural manipulation.
r2 -qc 'iS' <binary> # Section table r2 -qc 'iSS' <binary> # Sections with entropy
for s in pe.sections:
name = s.Name.decode().rstrip('\x00')
entropy = s.get_entropy()
raw = s.SizeOfRawData
virt = s.Misc_VirtualSize
ratio = virt / raw if raw > 0 else float('inf')
chars = s.Characteristics
rwx = f"{'R' if chars & 0x40000000 else '-'}{'W' if chars & 0x80000000 else '-'}{'X' if chars & 0x20000000 else '-'}"
packed = "PACKED" if entropy > 7.0 else "HIGH" if entropy > 6.5 else ""
inflated = "INFLATED" if ratio > 10 else ""
print(f"{name:8s} raw={raw:>8d} virt={virt:>8d} ratio={ratio:>6.1f} entropy={entropy:.2f} {rwx} {packed} {inflated}")Red flags: entropy > 7.0, VirtualSize >> RawSize, RWX permissions, packer section names (.UPX, .aspack, .themida, .vmp).
See `references/section-analysis.md` for section deep dive.
Step 4 — Import Analysis
Imports reveal the binary's capabilities. Missing or minimal imports suggest packing or dynamic resolution.
r2 -qc 'ii' <binary> r2 -qc 'ii~CreateRemote' <binary> # Search for injection APIs r2 -qc 'ii~Virtual' <binary> # Search for memory manipulation
if hasattr(pe, 'DIRECTORY_ENTRY_IMPORT'):
for entry in pe.DIRECTORY_ENTRY_IMPORT:
dll = entry.dll.decode()
funcs = [i.name.decode() if i.name else f"ord#{i.ordinal}" for i in entry.imports]
print(f"{dll} ({len(funcs)} imports): {', '.join(funcs[:5])}{'...' if len(funcs) > 5 else ''}")
else:
print("NO IMPORT TABLE — likely packed or manually resolved")Few imports (< 5 functions) from kernel32.dll only = strong packing indicator. Look for LoadLibrary + GetProcAddress as the only imports -- this means the binary resolves everything at runtime.
See `references/import-export-tables.md` for import/export deep dive.
Step 5 — Resource Analysis
Resources can contain embedded
Other skills on fsociety.
More skills from other plugins.
api-security
Use for authorized security assessment of REST, GraphQL, WebSocket, or SOAP APIs, including discovery, authentication,…
abusing-dpapi-for-cred…
Extract and decrypt Windows DPAPI-protected secrets (Credential Manager, browser logins/cookies, Wi-Fi credentials, KeePass keys)…
clean-user-facing-text
Clean and finalize authorized natural-language text intended for readers by auditing suspicious invisible Unicode and rewriting…
Questions about pe-analysis.
- Which coding agents can use pe-analysis?
- pe-analysis installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

